TCP的长链接和UDP的socket服务
TCP链接一旦建立,这个链接会一直存在,即就是clent1和sever之间的链接会一直存在;因此clent2和sever之间无法构成链接(就相当于clent1和sever之间的电话一直占线,clent2打不进去)。只有将clent1和sever之间的链接断开才能将clent2和sever之间的链接链接上。
比如:
sever端口
import socket sk=socket.socket() sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) sk.bind(('127.0.0.1',8080)) sk.listen() #上面相当于服务器起了一个服务,等待别人来链接 conn,addr=sk.accept()#获取到一个客户端的链接,已经完成了三次握手,建立了一个链接 while 1: msg=conn.recv(1024).decode('utf-8') if msg=='bye':break print(msg) info=input('>>>>') if info=='bye': conn.send(b'bye') break conn.send(info.encode('utf-8')) conn.close() conn,addr=sk.accept()#获取到一个客户端的链接,已经完成了三次握手,建立了一个链接 while 1: msg=conn.recv(1024).decode('utf-8') if msg=='bye':break print(msg) info=input('>>>>') if info=='bye': conn.send(b'bye') break conn.send(info.encode('utf-8')) sk.close()#关闭socket对象,如果不关闭,还能够继续接收消息
clent1
import socket sk=socket.socket() sk.connect(('127.0.0.1',8080)) while 1: info=input('>>>>') if info=='bye': sk.send(b'bye') break sk.send(info.encode('utf-8'))#注意这里已经转成了bytes类型 ret=sk.recv(1024).decode('utf-8') if ret=='bye':break print(ret) sk.close()
clent2
import socket sk=socket.socket() sk.connect(('127.0.0.1',8080)) while 1: info=input('clent2:>>>>') if info=='bye': sk.send(b'bye') break sk.send(('clent2'+info).encode('utf-8'))#注意这里已经转成了bytes类型 ret=sk.recv(1024).decode('utf-8') if ret=='bye':break print(ret) sk.close()
这样能够实现,先跟clent1沟通,然后再跟clent2沟通。
代码进一步优化
sever端口
import socket sk=socket.socket() sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) sk.bind(('127.0.0.1',8080)) sk.listen() #上面相当于服务器起了一个服务,等待别人来链接 while 1: conn,addr=sk.accept()#获取到一个客户端的链接,已经完成了三次握手,建立了一个链接 while 1: msg=conn.recv(1024).decode('utf-8') if msg=='bye':break print(msg) info=input('>>>>') if info=='bye': conn.send(b'bye') break conn.send(info.encode('utf-8')) conn.close() sk.close()#关闭socket对象,如果不关闭,还能够继续接收消息
clent1端口和clent2端口代码保持不变
clent1端口
import socket sk=socket.socket() sk.connect(('127.0.0.1',8080)) while 1: info=input('>>>>') if info=='bye': sk.send(b'bye') break sk.send(info.encode('utf-8'))#注意这里已经转成了bytes类型 ret=sk.recv(1024).decode('utf-8') if ret=='bye':break print(ret) sk.close()
clent2端口
import socket sk=socket.socket() sk.connect(('127.0.0.1',8080)) while 1: info=input('clent2:>>>>') if info=='bye': sk.send(b'bye') break sk.send(('clent2'+info).encode('utf-8'))#注意这里已经转成了bytes类型 ret=sk.recv(1024).decode('utf-8') if ret=='bye':break print(ret) sk.close()
UDP的socket服务
初尝试
sever端
import socket sk=socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',8080)) msg,addr=sk.recvfrom(1024) print(msg.decode('utf-8')) sk.sendto(b'hello',addr) sk.close()
clent端
import socket sk=socket.socket(type=socket.SOCK_DGRAM) ip_port=('127.0.0.1',8080) sk.sendto(b'bye',ip_port) ret,addr=sk.recvfrom(1024) print(ret.decode('utf-8')) sk.close()
总结:udp的sever不需要进行监听也不需要连接,在启动服务之后只能被动的等待客户端发送消息过来,客户端发送消息的同时还会自带地址信息,消息回复的时候,不仅需要发送消息,还需要把对方的地址填上。
和多个人聊天
sever端
import socket sk=socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',8080)) while 1: msg,addr=sk.recvfrom(1024) if msg=='bye': break print(addr) print(msg.decode('utf-8')) info=input('sever:') info=('\033[34msever:%s\033[0m'%info).encode('utf-8') sk.sendto(info,addr) sk.close()
clent1
import socket sk=socket.socket(type=socket.SOCK_DGRAM) ip_port=('127.0.0.1',8080) while 1: info=input('clent1:') info = ('\033[31mclen1:%s\033[0m' % info).encode('utf-8')#这里修改了颜色 sk.sendto(info,ip_port) ret,addr=sk.recvfrom(1024) if ret=='bye': break print(ret.decode('utf-8')) sk.close()
clent2
import socket sk=socket.socket(type=socket.SOCK_DGRAM) ip_port=('127.0.0.1',8080) while 1: info=input('clent2:') info=('\033[32mclen2:%s\033[0m'%info).encode('utf-8') sk.sendto(info,ip_port) ret,addr=sk.recvfrom(1024) if ret=='bye': break print(ret.decode('utf-8')) sk.close()
作业:clent端发送时间,sever端,提供时间
修改颜色:参考https://www.cnblogs.com/Eva-J/p/8330517.html