UDP协议:
#coding=utf-8 from threading import Thread from socket import * #收数据 def receiveData(udpSocket,destIp,destPort): while True: content,destInfo = udpSocket.recvfrom(1024) print("\r【Receive from %s : %s】%s\nInput:"%(destInfo[0],destInfo[1],content.decode("gb2312")),end="") #发数据 def sendData(udpSocket,destIp,destPort): while True: sendInfo = input("Input:") udpSocket.sendto(sendInfo.encode('gb2312'),(destIp,destPort)) #udpSocket = None #destIp = "" #destPort = 0 #def main(): # global udpSocket,destIp,destPort # destIp = input("对方的IP:") # destPort = int(input("对方的端口:")) # #创建Socket对象 # udpSocket = socket(AF_INET,SOCK_DGRAM) # udpSocket.bind(("",4567)) # tr = Thread(target=receiveData) # ts = Thread(target=sendData) # # tr.start() # ts.start() # # tr.join() # ts.join() def main(): destIp = input("对方的IP:") destPort = int(input("对方的端口:")) #创建Socket对象 udpSocket = socket(AF_INET,SOCK_DGRAM) udpSocket.bind(("",4567)) tr = Thread(target=receiveData,args=(udpSocket,destIp,destPort)) ts = Thread(target=sendData,args=(udpSocket,destIp,destPort)) tr.start() ts.start() tr.join() ts.join() if __name__ == '__main__': main()
TCP协议:
服务端:
#coding=utf-8 from socket import * serverSocket = socket(AF_INET,SOCK_STREAM) #绑定端口 serverSocket.bind(("",8899)) #最大监听5个客户端 serverSocket.listen(5) while True: #接收到的客户端 clientSocket,clientInfo = serverSocket.accept() while True: #客户端的数据 recvData = clientSocket.recv(1024).decode("gb2312") if recvData != "end": print('客户端:%s;数据是:%s'%(str(clientInfo),recvData)) else: print('客户端:%s;会话结束.'%(str(clientInfo))) break clientSocket.close() serverSocket.close()
客户端:
#coding=utf-8 from socket import * clientSocket = socket(AF_INET,SOCK_STREAM) #连接服务端 serverInfo = ("192.168.1.107",8899) clientSocket.connect(serverInfo) #发送数据到服务端 clientSocket.send('hello'.encode('gb2312')) #接收到服务端的数据 recvData = clientSocket.recv(1024) print('接收到服务端:%s;数据是:%s'%(str(serverInfo),recvData.decode("gb2312"))) clientSocket.close()
IO多路复用之epoll:epoll(事件通知机制)比select(轮询机制)性能要好
server端:
import socket import select #创建套接字 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #设置可以重复使用绑定的信息 s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #绑定本机信息 s.bind(("",7788)) #变为被动 s.listen(10) #创建epoll对象 epoll = select.epoll() #将创建的套接字添加到epoll的事件监听中 #EPOLLIN 可读,EPOLLOUT可写,EPOLLET通知一次,EPOLLLT通知多次 epoll.register(s.fileno(),select.EPOLLIN|select.EPOLLET) connections = {} addresses = {} #循环等待客户端发送数据 while True: #获取所有可以收发的套接字--未指定超时时间则为阻塞等待 epoll_list = epoll.poll() #对事件进行判断 for fd,events in epoll_list: #如果是socket创建的套接字被激活 if fd == s.fileno(): conn,addr = s.accept() print('有新的客户端来到%s'%str(addr)) #将conn和addr信息分别保存起来 connections[conn.fileno()] = conn addresses[conn.fileno()] = addr #向epoll中注册连接socket的刻度事件 epoll.register(conn.fileno(),select.EPOLLIN|select.EPOLLET) elif events == select.EPOLLIN:#接收数据的事件 #从激活fd上接收 recvData = connections[fd].recv(1024) if len(recvData)>0: print('recv:%s'%recvData) else: #从epoll中移除该连接 epoll.unrgister(fd) #server侧主动关闭连接fd connections[fd].close() print("%s---offline--"%str(addresses[fd]))客户端:
#coding=utf-8 from socket import * clientSocket = socket(AF_INET,SOCK_STREAM) #连接服务端 serverInfo = ("127.0.0.1",7788) clientSocket.connect(serverInfo) #发送数据到服务端 clientSocket.send('hello'.encode('gb2312')) #接收到服务端的数据 recvData = clientSocket.recv(1024) print('接收到服务端:%s;数据是:%s'%(str(serverInfo),recvData.decode("gb2312"))) clientSocket.close()运行服务端:
[chaoge@localhost mypython]$ python3 epoll01.py
有新的客户端来到('127.0.0.1', 41358)
recv:b'hello'
有新的客户端来到('127.0.0.1', 41360)
recv:b'hello'
有新的客户端来到('127.0.0.1', 41362)
recv:b'hello'
运行客户端:
[chaoge@localhost ~]$ python3 mypython/socket02.py
接收到服务端:('127.0.0.1', 7788);数据是: