Day9 基于TCP的套接字和基于UDP的套接字

 1 服务端:
 2 ss=socket()    #创建服务器套接字 
 3 ss.bind()        #把地址绑定到套接字
 4 ss.listen()        #监听套接字,
 5 inf_loop:          #服务器无限循环  
 6     cs=ss.accept()    接受客户端连接
 7     comm_loop:        #通讯循环
 8         cs.recv()/cs.send()     #对话(接收与发送)
 9     cs.close()    #关闭客户端套接字
10 ss.close()        #关闭服务器套接字(可选)
11 
12 
13 #客户端
14 cs=socker()  #创建客户端套接字
15 cs.connet()   #尝试连接服务器
16 command_loop:  #通讯循环
17   cs.send()/cs.recv()  #对话(发送/接收)
18 cs.close()   #关闭客户端套接字

这是基于TCP连接的套接字模型。

UDP链接的套接字模型是这样的:

服务端:
ss=socket()    #创建一个服务器的套接字
ss.bind()         #绑定服务器套接字
inf_loop:         #服务器无限循环
    cs=ss.recvfrom()/ss.sendto()     #对话(接收与发送)
ss.cloes()    #关闭服务器套接字


客户端:
cs=socket()    #创建客户端套接字
comm_loop:    #通信循环
    cs.sendto()/cs.recvfrom()   #对话(发送和接收)
cs.close()      #关闭客户套接字

UDP的会话的无关先启动哪一端,先启动服务端或者客户端都不会报错。

而且当客户端发消息的时候,无论服务端收到或者收不到都不会报错;

客户端和服务端收到的消息都分为两部分,

(b"发送的内容",("127.0.0.1",4888)) 我们可以利用 data1,client_addr=udp_server.recvfrom(1024)这种方式来收取数据和对方的地址。

 1 #udp服务端
 2 from socket import *
 3 
 4 udp_server=socket(AF_INET,SOCK_DGRAM)
 5 udp_server.bind(('127.0.0.1',8080))
 6 
 7 while True:
 8     data,client_addr=udp_server.recvfrom(1024)
 9     print(data,client_addr)
10     udp_server.sendto(data.upper(),client_addr)
11 
12 
13 
14 #udp   client
15 from socket import *
16 
17 udp_client=socket(AF_INET,SOCK_DGRAM)
18 
19 while True:
20     msg=input('>>: ').strip()
21     udp_client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
22     data,server_addr=udp_client.recvfrom(1024)
23     print(data.decode('utf-8'))

基于TCP的连接,发送数据的时候可能会发生粘包(在数据量比较小,时间间隔比较短的情况下),所以我们要探讨下UDP会不会出现这种情况。

#测试代码:

 1 #udp    server
 2 from socket import *
 3 udp_server=socket(AF_INET,SOCK_DGRAM)
 4 udp_server.bind(('127.0.0.1',8080))
 5 
 6 data1,client_addr=udp_server.recvfrom(1)
 7 print('data1',data1)
 8 data2,client_addr=udp_server.recvfrom(1024)
 9 print('data2',data2)
10 
11 
12 
13 #udp   client
14 from socket import *
15 udp_client=socket(AF_INET,SOCK_DGRAM)
16 
17 udp_client.sendto('hello'.encode('utf-8'),('127.0.0.1',8080))
18 udp_client.sendto('world'.encode('utf-8'),('127.0.0.1',8080))

#通过代码测试我们可以清楚的看到,基于UDP的链接不会发生粘包现象

#但是当UDP发送的字节大于服务端(或者客户端)所接收的字节时,会报错。


实现并发的UDP链接:

#服务端
import socketserver
class MyUDPhandler(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.request)   
      #(b'aaa', <socket.socket fd=252, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=('127.0.0.1', 8080)>)打印出来是这种格式  #数据+用来给回消息的socket+地址
      self.request[
1].sendto(self.request[0].upper(),self.client_address) if __name__ == '__main__': s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyUDPhandler) #UDP的socket服务进程,()内的是地址和端口,后边跟的是自己定义的类 s.serve_forever()


 

原文地址:https://www.cnblogs.com/sexiaoshuai/p/7444691.html