精华内容
下载资源
问答
  • Python网络编程Socket应用,并解决了error:10054错误
    千次阅读
    2018-03-07 16:18:01

    首先我们写一个客户端:

    import socket
    
    # 客户端 发送一个数据,再接收一个数据
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #声明socket类型,同时生成链接对象
    client.connect(('localhost',6969)) #建立一个链接,连接到本地的6969端口
    
    while True:
        msg = input('>>:').strip()  #strip默认取出字符串的头尾空格
        client.send(msg.encode('utf-8'))  #发送一条信息 python3 只接收btye流
        data = client.recv(1024) #接收一个信息,并指定接收的大小 为1024字节
        print('recv:',data.decode()) #输出我接收的信息
    
    client.close() #关闭这个链接

    然后在写一个服务器端
    我们这里的服务器端是可以接收多个链接的,当第一个链接没有断开时,后面的链接一直等待,知道第一个链接终止,才会链接第二个..链接,依此类推。
    并且完美解决了error:10054的强制关闭服务器端的错误!

    import socket
    # 建立一个服务端
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('localhost',6969)) #绑定要监听的端口
    server.listen(5) #开始监听 表示可以使用五个链接排队
    
    while True:
    # conn就是客户端链接过来而在服务端为期生成的一个链接实例
        conn,addr = server.accept() #等待链接,多个链接的时候就会出现问题,其实返回了两个值
        print(conn,addr)
    
        while True:
            try:
                data = conn.recv(1024)  #接收数据
                print('recv:',data.decode()) #打印接收到的数据
                conn.send(data.upper()) #然后再发送数据
            except ConnectionResetError as e:
                print('关闭了正在占线的链接!')
                break
        conn.close()
    
    server.close() #然后关闭服务

    测试方法,先运行服务器端脚本,
    然后运行客户端脚本,并发送信息,
    再次打开运行一个客户端脚本,并发送信息。
    会发现,会在等待第一个链接断开,当第一个链接断开的时候就会开启第二个链接,这里已经解决了当起一个链接断开的时候强制关闭服务器端。

    更多相关内容
  • 本文实例讲述了python网络编程socket实现服务端、客户端操作。分享给大家供大家参考,具体如下: 本文内容: socket介绍 TCP: 服务端 客户端 UDP: 服务端 客户端 首发时间:2018-02-08 01:14 修改: 2018-03...
  • 主要为大家详细介绍了python网络编程之多线程同时接受和发送,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • python网络编程socket

    千次阅读 2022-01-09 18:00:05
    socket 为了保证数据的完整性和可靠性我们使用 tcp 传输协议进行数据的传输,udp是不管有没有建立连接成功都会进行发送,...负责进程之间的网络数据传输,只要跟网络相关的应用程序或者软件都使用到了 socket ...

    目录

    socket

    创建客户端 socket 对象

    创建服务端 socket 对象 

     多线程服务器端

    socket之send和recv原理剖析

    1. 认识TCP socket的发送和接收缓冲区

    2. send原理剖析

    3. recv原理剖析

    4. send和recv原理剖析图


    socket

    为了保证数据的完整性和可靠性我们使用 tcp 传输协议进行数据的传输,udp是不管有没有建立连接成功都会进行发送,如飞Q,邮件,为了能够找到对应设备我们需要使用 ip 地址,为了区别某个端口的应用程序接收数据我们需要使用端口号,那么通信数据是如何完成传输的呢?

    使用 socket 来完成

    负责进程之间的网络数据传输,只要跟网络相关的应用程序或者软件都使用到了 socket

    TCP 网络应用程序开发分为:

    • TCP 客户端程序开发
    • TCP 服务端程序开发

    客户端:

    步骤说明:

    1. 创建客户端套接字对象
    2. 和服务端套接字建立连接
    3. 发送数据
    4. 接收数据
    5. 关闭客户端套接字

    服务器

    步骤说明:

    1. 创建服务端端套接字对象
    2. 绑定端口号
    3. 设置监听
    4. 等待接受客户端的连接请求
    5. 接收数据
    6. 发送数据
    7. 关闭套接字

    导入 socket 模块 import socket

    创建客户端 socket 对象

     socket.socket(AddressFamily, Type)

    参数说明:

    • AddressFamily 表示IP地址类型, 分为TPv4和IPv6
    • Type 表示传输协议类型

    方法说明:

    • connect((host, port)) 表示和服务端套接字建立连接, host是服务器ip地址,port是应用程序的端口号
    • send(data) 表示发送数据,data是二进制数据
    • recv(buffersize) 表示接收数据, buffersize是每次接收数据的长度

    代码分析:

    socket是遵循tcp/ip协议的,创建socket对象传入两参数,

    并与服务器去建立连接 传入服务器ip port 元组

    发送二进制数据,并编码

    接收二进制数据并解码,

    最后关闭socket,

    一句话:socket对象与服务器连接后发送数据 或接收数据

    import socket
    
    if __name__=='__main__':
        # 创建socket对象,并传入tcp/ip,
        # socket.AF_INET ipv4
        # socket.SOCK_STREAM tcp
        tcp_client_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        tcp_client_socket.connect(('192.168.0.112',8989))
        # 发送二进制数据
        tcp_client_socket.send('你好'.encode('utf8'))
        # 接收二进制数据并解码
        res=tcp_client_socket.recv(1024).decode('utf8')
        print('收到服务器的消息:',res)
        tcp_client_socket.close()

    创建服务端 socket 对象 

    • bind((host, port)) 表示绑定端口号, host 是 ip 地址,port 是端口号,ip 地址一般不指定,表示本机的任何一个ip地址都可以。
    • listen (backlog) 表示设置监听,backlog参数表示最大等待建立连接的个数。
    • accept() 表示等待接受客户端的连接请求
    • send(data) 表示发送数据,data 是二进制数据
    • recv(buffersize) 表示接收数据, buffersize 是每次接收数据的长度

     代码分析创建socket对象,

    程序结束立即释放端口号

    绑定端口号设置监听客户端连接的个数

    等待客户端的连接,之后接收客户端的请求

    import socket
    
    if __name__=='__main__':
        tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # 程序退出端口号立即释放
        tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
        # 绑定端口号
        tcp_server_socket.bind(('',8989))
        # 监听最多128个连接数
        tcp_server_socket.listen(128)
        # 等待客户端的连接请求,只有连接后程序才会往下执行
        # 建立连接后获取的2个参数   1和客户端通信的套接字,2客户端端口号
        # 建立连接后TCP 服务器端程序会产生一个新的套接字,收发客户端消息使用该套接字
        service_client_socket,ip_port=tcp_server_socket.accept()
        print(ip_port)
        # 接收客户端消息
        recv_data=service_client_socket.recv(1024)
        #服务端可以通过返回数据的长度来判断客户端是否已经下线
        recv_data_length=len(recv_data)
        recv_content=recv_data.decode('utf8')
        print(recv_content)
        send_data = "ok, 问题正在处理中...".encode("utf8")
        # 发送数据给客户端
        service_client_socket.send(send_data)
        # 关闭服务与客户端的套接字, 终止和客户端通信的服务
        service_client_socket.close()
        tcp_server_socket.close()

    说明:

    当客户端和服务端建立连接后,服务端程序退出后端口号不会立即释放,需要等待大概1-2分钟。

    解决办法有两种:

    1. 更换服务端端口号
    2. 设置端口号复用(推荐大家使用),也就是说让服务端程序退出后端口号立即释放。

    设置端口号复用的代码如下:

    # 参数1: 表示当前套接字
    # 参数2: 设置端口号复用选项
    # 参数3: 设置端口号复用选项对应的值
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

     多线程服务器端

    import socket
    import threading
    import time
    
    
    def handle_client_request(service_client_socket, ip_port):
        # 循环处理请求
        while True:
            time.sleep(5)
            data=service_client_socket.recv(1024)
            # 若存在数据,即消息长度不是0 则打印 长度为0则客户端下线
            if data:
                print('客户端发来的消息',data.decode('utf8'),'端口号',ip_port)
                # 特别注意:客户端服务端一旦连接,双方的收发必须一一对应,有发就有收,毕竟是基于TCP协议的,
                # 不然就成UDP协议的了
                service_client_socket.send("ok,问题正在处理中...".encode("utf8"))
            else:
                print('客户端下线了')
                break
        service_client_socket.close()
    
    if __name__=='__main__':
        tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
        tcp_server_socket.bind(('',8989))
        tcp_server_socket.listen(128)
        # 准备工作做完后循环执行
        while True:
            #  等待接收客户端的连接请求
            service_client_socket,ip_port=tcp_server_socket.accept()
            # 一旦走到这说明建立连接成功,连接后开启子线程完成多任务
            #传入处理客户端请求的新socket和端口号
            sub_t=threading.Thread(target=handle_client_request,args=(service_client_socket,ip_port),daemon=True)
            # 此时需要开启守护主线程,因为建立连接后才执行到子线程处理,此时若再子线程工作的时候客户端断开连接了
            # 主线程无法正常断开连接
            #分析:子线程执行需要5秒  再5秒内被客户端强制退出 导致子线程未执行完主线程就挂掉了
            #Error 10054] 远程主机强迫关闭了一个现有的连接,要求子线程跟随主线程的生命周期
            sub_t.start()
            # 这里不用关闭服务器socket  让其一直可以接收客户端发消息

    socket之send和recv原理剖析

    1. 认识TCP socket的发送和接收缓冲区

    当创建一个TCP socket对象的时候会有一个发送缓冲区和一个接收缓冲区这个发送和接收缓冲区指的就是内存中的一片空间。

    2. send原理剖析

    send是不是直接把数据发给服务端?

    不是,要想发数据,必须得通过网卡发送数据,应用程序是无法直接通过网卡发送数据的,它需要调用操作系统接口,也就是说,应用程序把发送的数据先写入到发送缓冲区(内存中的一片空间),再由操作系统控制网卡把发送缓冲区的数据发送给服务端网卡 

    3. recv原理剖析

    recv是不是直接从客户端接收数据?

    不是,应用软件是无法直接通过网卡接收数据的,它需要调用操作系统接口,由操作系统通过网卡接收数据,把接收的数据写入到接收缓冲区(内存中的一片空间),应用程序再从接收缓存区获取客户端发送的数据

    4. send和recv原理剖析图

     

    说明:

    • 发送数据是发送到发送缓冲区
    • 接收数据是从接收缓冲区 获取
    展开全文
  • Python中实现socket通信的服务端比较复杂,而客户端非常简单,所以客户端基本上都是用sockct模块...desc:socket编程客户端,python3.6.2 ''' import socket,sys HOST = '192.168.1.6' PORT = 8998 ADDR =(HOST,PORT)
  • socket又称“套接字”, 应用程序通常通过“套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。 socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: ...

    什么是Socket

    socket又称“套接字”, 应用程序通常通过“套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

    socket()函数

    Python 中,我们用 socket()函数来创建套接字,语法格式如下:

    socket.socket(family, type, protocol)
    

    参数: family: 套接字家族可以使AF_UNIX或者AF_INET
    type:套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM
    protocol: 一般不填默认为0.

    socket 对象内建方法

    函数 描述
    服务器端套接字:

    s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。

    s.listen() 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。

    s.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来 客户端套接字

    s.connect() 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

    s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

    公共用途的套接字函数

    s.recv() 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。

    s.send() 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。

    s.sendall() 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

    s.recvfrom() 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。

    s.sendto() 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。

    s.close() 关闭套接字

    s.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。

    s.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)

    s.setsockopt(level,optname,value) 设置给定套接字选项的值。

    s.getsockopt(level,optname[.buflen]) 返回套接字选项的值。

    s.settimeout(timeout) 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())

    s.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。

    s.fileno() 返回套接字的文件描述符。

    s.setblocking(flag) 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。

    s.makefile() 创建一个与该套接字相关连的文件

    -----**** 上述来源于网络 ****-----------

    实例:实现文件传输

    实例演示:

    服务器端打开
    在这里插入图片描述
    客户端运行,选择文件上传
    在这里插入图片描述
    客户端文件上传完毕
    在这里插入图片描述
    服务器端收到文件
    在这里插入图片描述
    注:本次演示不是在局域网上,而是在实际上的服务器上的文件传输演示

    源代码:

    客户端

    """
    author: 全洛
    
    """
    import socket
    import easygui as eg
    import json
    import os
    import time
    
    '''读取配置文件'''
    f = open('clientconf.json', 'r', encoding='utf-8')
    date = json.load(f)
    ip = date.get('IP')
    port = date.get('port')
    f.close()
    
    '''创建socket对象'''
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    try:
        '''连接服务器, 指定IP和端口'''
        client.connect((ip, port))
    
        '''接收小于 1024 字节的数据'''
        msg = client.recv(1024)
    
        '''输出连接成功信息'''
        print(msg.decode('utf-8'))
    except Exception as e:
        print(f'连接服务器失败', e)
    else:
        '''选择发送的文件'''
        filepath = eg.fileopenbox(title='选择文件')
        '''获取文件名,文件大小'''
        filename = filepath.split("\\")[-1]
        filesize = os.path.getsize(filepath)
        # 先将文件名传过去
        # 编码文件名
        client.send(filename.encode())
        time.sleep(0.5)
        # 再将将文件大小传过去
        # 编码文件大小
        client.send(filesize.to_bytes(filesize.bit_length(), byteorder='big'))
        try:
            '''传输文件'''
            start_time = time.time()
            with open(filepath, 'rb') as f:
                size = 0
                while True:
                    #读取文件数据,每次1024KB
                    f_data = f.read(1024)
                    # 数据长度不为零,传输继续
                    if f_data:
                        client.send(f_data)
                        size += len(f_data)
                        if time.time() - start_time == 0:
                            time.sleep(0.5)
                        speed = (size) / (time.time() - start_time)
                        print('\r' + '【上传进度】:%s%.2f%%, Speed: %.2fMB/s' % ('>' * int(size * 50 / filesize), float(size / filesize * 100), float(speed / 1024 / 1024)), end=' ')
                    # 数据长度为零传输完成
                    else:
                        print(f'{filename},{float(filesize/1024/1024):.2f}MB, 传输完成')
                        break
        except Exception as e:
            print(f'传输异常', e)
    finally:
        '''关闭客户端'''
        client.close()
    

    客户端配置:
    {
    “IP”: “182.92.112.155”,
    “port”: 3636
    }

    服务器端

    """
    author: 全洛
    
    """
    import socket
    import os
    import json
    import threading
    import time
    
    
    '''导入配置文件'''
    f = open('serverconf.json', 'r', encoding='utf-8')
    dirsave = json.load(f).get('dirSave')
    f.close()
    if not os.path.exists(dirsave):  # 看是否有该文件夹,没有则创建文件夹
        os.mkdir(dirsave)
    
    class server:
        def __init__(self):
            ''''''
            ''' 创建socket对象'''
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
            '''获取本地'''
            self.host = socket.gethostname()
    
            '''设置端口'''
            self.port = 3636
    
            '''绑定地址'''
            self.server.bind((self.host, self.port))
    
            '''设置最大连接数, 超过后排队'''
            self.server.listen(12)
    
            print('服务器已上线\n等待客户端连接...\n')
    
        def server100(self):
            while True:
                '''建立客户端连接'''
                client, addr = self.server.accept()
                print(f'客户端: {str(addr)}, 连接上服务器')
                msg = f'已连接到服务器{self.host}!\r\n'
                client.send(msg.encode('utf-8'))
                # 有客户端连接后,创建一个线程给客户端
                t1 = threading.Thread(self.taskfilethread(client))
                # 设置线程守护
                t1.setDaemon(True)
                # 启动线程
                t1.start()
    
        def taskfilethread(self, client):
            '''接收文件名,文件大小'''
            filename = client.recv(1024)
            # time.sleep(0.5)
            filesize = client.recv(1024)
            # 解码文件名,文件大小
            filename = filename.decode()
            filesize = int.from_bytes(filesize, byteorder='big')
            '''接收文件'''
            try:
                f = open(dirsave+"\\"+ filename, 'wb')
                size = 0
                start_time = time.time()
                while True:
                    # 接收数据
                    f_data = client.recv(1024)
                    # 数据长度不为零,接收继续
                    if f_data:
                        f.write(f_data)
                        size += len(f_data)
                        if time.time() - start_time == 0:
                            time.sleep(0.5)
                        speed = (size) / (time.time() - start_time)
                        print('\r' + '【下载进度】:%s%.2f%%, Speed: %.2fMB/s' % ('>' * int(size * 50 / filesize), float(size / filesize * 100), float(speed/1024/1024)),end=' ')
                    # 数据长度为零接收完成
                    else:
                        break
            except Exception as e:
                print(f'接收异常', e)
            else:
                f.flush()
                print(f'{filename},{float(filesize/1024/1024):.2f}MB, 接收完成')
                f.close()
    
    if __name__ =='__main__':
        server = server()
        server.server100()
    

    服务器端配置:
    {
    “dirSave”: “C:\Users\Administrator\Desktop\temp”
    }


    最后

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/weixin_43347550/article/details/106199850
    ————————————————

    展开全文
  • Python socket网络编程 初学 python,前段时间买了两本书《python 编程从入门到实践》《Python 核心编程第三版》,第一本书主要讲的是一些基本语法和一些基本的使用方法,而第二本则深入很多,自己看来也是一知半解...
  • python socket 网络编程

    2019-01-19 10:30:03
    本代码主要是关于python socket网络编程,可以实现文件上传 文件下载 以及远程命令行的执行
  • 主要介绍了Python 网络编程之UDP发送接收数据功能,结合实例形式分析了Python使用socket套接字实现基于UDP协议的数据发送端与接收端相关操作技巧,需要的朋友可以参考下
  • Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要...本文主要介绍使用Python 进行TCP Socket 网络编程,假设你已经具有初步的网络知识及Python 基本语法知识。 TCP 是一种面向连接的传输层协议,TCP Sock
  • 一,粘包问题详情 ...若连续几次需要send的数据都很少,通常TCP socket 会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据。 2,首先需要掌握一个socket收发消息的原理 发
  • 在使用socket进行网络编程中,如何判定对端发送一条报文是否接收完成,是进行socket网络开发必须要考虑的一个问题。这里,简要介绍一下判别数据接收接收完成常用的三种方法: 1.基础数据接收法: 使用基础数据接收法...
  • 由于网络课需要实现Socket网络编程,所以简单实现了一下,C/S模式分别用TCP/IP协议与UDP协议实现,下面将分别讲解。 TCP/IP协议 TCP/IP协议是面向连接的,即客户端与服务器需要先建立连接后才能传输数据,以下是...
  • 一、实验目标: 掌握基于SOCKET网络编程方法。 基于Python语言,编写一个网络应用程序。 二、实验内容 即时通信小程序(基于套接字)。
  • 什么是网络网络是由节点和连线构成,表示诸多对象及其相互联系。在数学上,网络是一种图,一般认为专指加权图。网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类型的实际问题中抽象出来的模型。在...
  • 本代码是python实现的socket实例代码,包括客户端和服务端。 server.py为服务端。 client.py为客户端。
  • 答:网络编程也叫做socket编程即套接字编程,基于遵循socket套接字的规定进行的编程 2.什么是socket? 答:socket就是一组简单的接口!socket抽象层位于TCP运输层和应用层之间,socket抽象层将TCP协议以及其他的协议...
  • 在本教程中,您将首先学习一些 Python的基础知识,并了解 Python 是如何成为一种很好的网络编程语言的。然后您将着重了解 Python 的基本 socket 特性,我们使用了一个样例聊天程序作为参考;并了解一下可以提供异步...
  • Python网络编程socket编程

    万次阅读 多人点赞 2018-05-13 14:28:38
    Win10python - 3.5 Socket工作原理和基本概念 Socket的中文翻译是套接字,它是TCP/IP网络环境下应用程序与底层通信驱动程序之间运行的开发接口,它可以将应用程序与具体的TCP/IP隔离开来,使得应用程序不需要了解...

    Win10

    python - 3.5

     

    Socket工作原理和基本概念

           Socket的中文翻译是套接字,它是TCP/IP网络环境下应用程序与底层通信驱动程序之间运行的开发接口,它可以将应用程序与具体的TCP/IP隔离开来,使得应用程序不需要了解TCP/IP的具体细节,就能够实现数据传输。

           在网络应用程序中,Socket通信是基于客户端/服务器结构。客户端是发送数据的一方。服务器时刻准备接受来自客户端的数据,对做出响应

           实现基于tcp网络通信与现实中打电话很像:

    1)      客户端(相当于打电话的一方),需要了解服务器的ip地址,如果该服务器有多个网络应用程序,单单ip地址则不够,这时候socket通信借用tcp/ip中端口的概念,不同应用程序使用不同端口通信(这就很类似电话分机)。

    2)      服务器应用程序必须早于客户端启动,并在指定ip地址和端口上执行监听,端口被占用,服务器则无法正常启动。(服务器处于监听状态就类似电话接通好电话线,等待被拨打的状态)

    3)      客户端在申请发送数据时,服务器端应用程序必须有足够的时间响应才能进行正常通信(电话响,却无人接听)。通常情况下,服务器的应用程序都需要具备同时处理多个客户端请求的能力,应用程序设计不合理或访问量过高都会导致响应超时。

    4)      使用Socket协议进行通信的双方必须使用相同的通信协议,Socket支持的底层通信协议包括tcp和udp两种,通信过程中,双方还必须采用相同的字符编码,按照约定的方式进行通信(打电话时,双方必须语言相同,才能进行信息交流)

    5)      通信时,物理网络必须保持通畅,否则通信将会中断(电话线有效,且连接正常)。

    6)      通信结束之前,客户端和服务器端都可以中断连接(任何一方都可以挂电话)。

     

    TCP是基于连接的通信协议,即先建立稳定连接后,再数据传输

    如果Socket通信基于UDP,则数据传输前不需要连接,类似发短信或发电报,即使对方不在线,也可以发送数据,发送的数据在指定时间没有得到对方响应,则视为操作超时,可以选择超时后重新发送数据。

    Socket编程的层次结构

    应用层

    Socket开发接口

    传输层

    TCP

    UDP

    网络层

    IP

    驱动

    物理层

     

    基于TCP的Socket编程

    面向连接的Socket通信是基于TCP的

     

    服务器程序要先与客户机程序启动,步骤以及调用函数:

    1)      调用socket()函数创建一个流式套接字,返回套接字号s

    2)      调用bind()将s绑定到已知地址,通常为本地ip

    3)      调用listen()将s设为监听模式,准备接收来自各客户端的连接请求

    4)      调用accept()等待接受客户端连接请求

    5)      如果接收到客户端请求,则accept()返回,得到新的套接字ns

    6)      调用rev()接收来自客户端的数据,调用send()向客户端发送数据

    7)      与客户端通信结束,服务器端可以调用shutdown()对方不再接收和发送数据,也可以由客户端程序断开连接,断开连接后,服务器进程调用closesocket()关闭套接字ns,此后服务器返回第四步

    8)      如果要退出服务器程序,则调用closesocket()关闭最初的套接字s

     

    客户端程序步骤以及调用函数:

    1)      调用WSAStartup()函数加载Windows Sockets动态库,然后调用socket()函数创建一个流式套接字,返回套接字号s。

    2)      调用connect()函数将套接字s连接到服务器。

    3)      调用send()函数向服务器发送数据,调用recv()函数接收来自服务器的数据。

    4)      与服务器的通信结束后,客户端程序可以调用close()函数关闭套接字。

    相关函数:

    1.socket()函数

    socket()函数用于创建与指定的服务提供者绑定套接字,函数原型如下:

    socket=socket.socket(familly,type)

    参数说明如下:

    familly,指定协议的地址家族,可为AF_INET或AF_UNIX。AF_INET家族包括Internet地址,AF_UNIX家族用于同一台机器上的进程间通信。

    type,指定套接字的类型。

    套接字类型

    说    明

    SOCK_STREAM

    提供顺序、可靠、双向和面向连接的字节流数据传输机制,使用TCP

    SOCK_DGRAM

    支持无连接的数据报,使用UDP

    SOCK_RAW

    原始套接字,可以用于接收本机网卡上的数据帧或者数据包

     

    2.bind()函数

    bind()函数可以将本地地址与一个Socket绑定在一起,函数原型如下:

    socket.bind( address )

    参数address是一个双元素元组,格式是(host,port)。host代表主机,port代表端口号。

     

    3.listen()函数

    listen()函数可以将套接字设置为监听接入连接的状态,函数原型如下:

    listen(backlog);

    参数backlog指定等待连接队列的最大长度。

     

    4.accept()函数

    在服务器端调用listen()函数监听接入连接后,可以调用accept()函数来等待接受连接请求。accept()的函数原型如下:

    connection, address = socket.accept()

    调用accept()方法后,socket会进入waiting状态。客户请求连接时,accept()方法会建立连接并返回服务器。accept()方法返回一个含有两个元素的元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。

     

    5.recv()函数

    调用recv()函数可以从已连接的Socket中接收数据。recv()的函数原型如下:

    buf = sock.recv(size)

    参数sock是接收数据的socket对象,参数size指定接收数据的缓冲区的大小。recv()的函数的返回接收的数据。

     

    6.send()函数

    调用send()函数可以在已连接的Socket上发送数据。send()的函数原型如下:

    sock.recv(buf)

    参数sock是在已连接的Socket上发送数据。参数buf是也要已连接的Socket上发送数据。

     

    7.close()函数

    close ()函数用于关闭一个Socket,释放其所占用的所有资源。socket()的函数原型如下:

    s.closesocket();

    参数s表示要关闭的Socket。

     

    使用socket通讯的简易服务器
           
    connection.close()

    import socket


    if __name__ == "__main__":
       
    #创建socket对象s,基于internet地址和tcp协议
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
       
    #绑定到本地的8001端口
        s.bind(("localhost",8001))
       
    #在本地8001端口监听,等待连接队列最大长度为5
        s.listen(5)
       
    print("等待连接")
       
    while True:
           
    #接收来自客户端的连接
           
    connection,address = s.accept()
           
    try:
               
    connection.settimeout(5)
               
    buf = connection.recv(1024).decode('utf-8')#接收客户端消息
               
    if buf=='1':
                   
    connection.send(b'welcome to server')
               
    else:
                   
    connection.send(b'please go out')
           
    except s.timeout:
               
    print('time out')
           
    connection.close()

     

    使用socket进行通信的建议客户端
       

    import socket


    import time
    if __name__ == '__main__':
       
    s =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
       
    s.connect(('localhost',8001))
       
    #推迟执行
       
    time.sleep(2)
       
    s.send(b'1')
       
    print(s.recv(1024).decode('utf-8'))
       
    s.close()

     

    基于TCP的Socket编程


    面向连接的Socket通信是基于TCP的


    由流程可以看出面向非连接的Socket通信流程比较简单,在服务器上不需要listen()和accept()来等待客户端连接,客户端程序不需要雨服务器建立连接,而是直接向服务器发送数据。

     

    1.     sendto()函数

    使用sendto()函数可以实现发送数据的功能,函数原型如下;

    s.sendto(data,(addr,port))

    参数说明如下:

      s,指定一个Socket句柄。

      data,要传输数据。

      addr,接收数据的计算机的IP地址。

      port,接收数据的计算机的端口。

    示例:import socket
    
    #创建UDP SOCKET
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    port = 8000 #服务器端口
    host = '192.168.0.101'#服务器地址
    while True:
        msg = input()# 接受用户输入
        if not msg:
           break
        # 发送数据
        s.sendto(msg.encode(),(host,port))
    s.close()

    2.     recvfrom()函数

    使用recvfrom ()函数可以实现接收数据的功能,函数原型如下;

    data,addr = s.recvfrom( bufsize);

    参数说明如下:

      s,指定一个Socket句柄。

      bufsize,接收数据的缓冲区的长度,单位为字节。

      data,接收数据的缓冲区。

      addr,发送数据的客户端的地址。

    示例:

    import socket

    #创建基于UDP的socket对象用socket.SOCK_DGRAM
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    s.bind((
    'localhost',8000))

    #循环调用recvfrom()接收客户端发送来的数据

    while True:

        data,addr = s.recvfrom(1024)
       
    if not data:
           
    print('client has exited!')
           
    break
     
      
    print('received:',data,'from',addr)
    s.close()

     


    展开全文
  • 网络五子棋游戏设计的难点在于对方进行通信,这里使用面向非连接的Socket编程Socket编程用于C/S开发,在这类应用中,客户端和服务器端通常需要先建立连接,然后发送和接收数据,交互完成后需要断开连接,本章采用...
  • python 网络编程socket

    千次阅读 2016-10-09 15:31:29
    socket模块详解,通过这些基础知识可以使我们更好的理解网络编程。 一、网络知识的一些介绍 1、socket网络连接端点。 例说:当你的Web浏览器请求www.jb51.net上的主页时(即就是发送HTTP请求),web浏览器会创建...
  • 主要介绍了Python网络编程使用select实现socket全双工异步通信功能,简单说明了select模块的功能及socket全双工异步通信功能的相关实现技巧,需要的朋友可以参考下
  • 本文实例讲述了python网络编程,分享给大家供大家参考。 具体方法如下: 服务端代码如下: from SocketServer import(TCPServer as TCP, StreamRequestHandler as SRH) from time import ctime HOST = '' PORT = ...
  • 主要介绍了Python 网络编程之TCP客户端/服务端功能,结合实例形式分析了Python使用socket套接字实现TCP协议下的客户端与服务器端数据传输操作技巧,需要的朋友可以参考下
  • import sockets = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 2. 绑定一个端口 s.bind((“”, 8081)) 3. 接受来自客户端的消息 while True: # Receive up to 1,024 bytes in a datagram ...
  • 一、套接字套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象。它们允许程序接受并进行连接,如发送和接受数据。为了建立通信通道,网络通信的每个...
  • python网络socket基础练习
  •  建立网络通信连接至少要一对端口号(Socket),Socket本质是编程接口(API),对TCP/IP的封装,提供了网络通信能力。  每种服务都打开一个Socket,并绑定到端口上,不同的端口对应不同的服务,就像ht

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,901
精华内容 22,760
关键字:

python网络编程socket