常用的套接字有两种tcp和udp
-
tcp跟打电话类似,客户端向服务器发送消息时首先要建立连接(即服务器只有接起电话的过程)* 后,两者才能交流,同时交流的时候能确保每一条消息都能传送给对方。
-
udp则类似邮政服务,客户端不用查询服务器的状态,直接发送消息(快件)即可,客户端不管服务器是否接受到该快件,这样做的好处是更加快速
实验
1、tcp
1.1 服务器端(server.py)
from socket import * from time import ctime HOST = '' ## 默认为本机IP地址 PORT = 21567 ## 端口号 BUFSIZE = 1024 ## 每次传送1MB ADDR = (HOST, PORT) """ socket第一个参数AF_INETb时IPV4, 如果时IPV6,则使用AF_INET6, 第二个参数SOCK_STREAM表示TCP协议, 如果是UDP,则使用SOCK_DGRAM """ from socket import * from time import ctime HOST = '' PORT = 21567 ## 端口号 BUFSIZE = 1024 ## 每次传送1MB ADDR = (HOST, PORT) """ socket第一个参数AF_INETb时IPV4, 如果时IPV6,则使用AF_INET6, 第二个参数SOCK_STREAM表示TCP协议, 如果是UDP,则使用SOCK_DGRAM """ tcpSerSock = socket(AF_INET, SOCK_STREAM) tcpSerSock.bind(ADDR) ## 将端口绑定到socket上 tcpSerSock.listen(5) ## 设置socket最大同时连接数为5 while True: print("waiting for connection...") tcpCliSock, addr = tcpSerSock.accept() ## 等待客户端连接 (联想到操作系统的进程等待) print("... connected from:", addr) ## 客户端连接成功进入无限循环(联想到操作系统的进程唤醒) while True: data = tcpCliSock.recv(BUFSIZE) ## 接受客户端消息 if not data: break tcpCliSock.send(bytes('[%s] %s' % (ctime(), ctime()), "utf-8")) ##向客户端返回时间消息 tcpCliSock.close() tcpSerSock.close() ## 关闭socket
1.2 客户机端(client.py)
from socket import * HOST = '127.0.0.1' PORT = 21567 ## 端口号 BUFSIZE = 1024 ## 每次传送1MB ADDR = (HOST, PORT) tcpCliSock = socket(AF_INET, SOCK_STREAM) ## 创建SOCKET tcpCliSock.connect(ADDR) ## 连接客户端 while True: data = input('> ') ## 待发送信息 if not data: break tcpCliSock.send(bytes(data, encoding='utf-8')) ## 发送信息 data = tcpCliSock.recv(BUFSIZE) ## 接受信息 if not data: break print(data.decode('utf-8')) ## 用utf-8解码接受到的字节流 tcpCliSock.close() ## 关闭socket
1.3 运行结果
可以看到客户端只和服务器连接了一次,即建立连接之后就可以一直发送消息了。
1.4 注意点
由于python3的问题,在接受和发送的时候只能传输字节流数据,因此在需要将字符串转成bytes才能正常运行!!!
1.5 进一步思考
其实示例代码并不是完全没有问题的,假设存在这样一i中可能,有服务器为A, 客户端B和C, B与A建立连接后, C不能与A建立连接,说好的最大连接数呢,C只有在B与A通话结束后才能建立连接并通话,下一步就是要解决这个问题。
2、 udp
2.1 服务器(server.py)
from socket import * from time import ctime HOST = '' PORT = 21567 ## 端口号 BUFSIZE = 1024 ## 每次传送1MB ADDR = (HOST, PORT) """ socket第一个参数AF_INETb时IPV4, 如果时IPV6,则使用AF_INET6, 第二个参数SOCK_STREAM表示TCP协议, 如果是UDP,则使用SOCK_DGRAM """ udpSerSock = socket(AF_INET, SOCK_DGRAM) udpSerSock.bind(ADDR) ## 将端口绑定到socket上 ## udp套接字没有最大连接数这一个参数 while True: print("waiting for message...") data, addr = udpSerSock.recvfrom(BUFSIZE) ##无需连接,直接接受消息 udpSerSock.sendto(bytes('[%s] %s' % (ctime(), data), "utf-8"), addr) ## 返回消息 print("... received from and return to:", addr) udpSerSock.close() ## 关闭socket
2.2 客户端(client.py)
from socket import * HOST = '127.0.0.1' PORT = 21567 ## 端口号 BUFSIZE = 1024 ## 每次传送1MB ADDR = (HOST, PORT) udpCliSock = socket(AF_INET, SOCK_DGRAM) ## 创建SOCKET ## 无需连接服务器端 while True: data = input('> ') ## 待发送信息 if not data: break udpCliSock.sendto(bytes(data, encoding='utf-8'), ADDR) ## 发送信息 data, ADDR = udpCliSock.recvfrom(BUFSIZE) ## 接受信息 if not data: break print(data.decode('utf-8')) ## 用utf-8解码接受到的字节流 udpCliSock.close() ## 关闭socket
2.3 运行截图udp服务器没有连接数量的限制
来源:51CTO
作者:tiny_Sean
链接:https://blog.csdn.net/qq_37904988/article/details/101060895