socket模块实现基于UDP聊天模拟程序;socketserver模块实现服务端 socket客户端代码示例
socket模块
serSocket.setblocking(False) 设置为非阻塞;
#coding=utf-8 from socket import * import time # 用来存储所有的新链接的socket g_socketList = [] def main(): serSocket = socket(AF_INET, SOCK_STREAM) serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1) localAddr = ('', 7788) serSocket.bind(localAddr) #可以适当修改listen中的值来看看不同的现象 serSocket.listen(1000) #将套接字设置为非堵塞 #设置为非堵塞后,如果accept时,恰巧没有客户端connect,那么accept会 #产生一个异常,所以需要try来进行处理 serSocket.setblocking(False) while True: #用来测试 #time.sleep(0.5) try: newClientInfo = serSocket.accept() except Exception as result: pass else: print("一个新的客户端到来:%s"%str(newClientInfo)) newClientInfo[0].setblocking(False) g_socketList.append(newClientInfo) # 用来存储需要删除的客户端信息 needDelClientInfoList = [] for clientSocket,clientAddr in g_socketList: try: recvData = clientSocket.recv(1024) if len(recvData)>0: print('recv[%s]:%s'%(str(clientAddr), recvData)) else: print('[%s]客户端已经关闭'%str(clientAddr)) clientSocket.close() g_needDelClientInfoList.append((clientSocket,clientAddr)) except Exception as result: pass for needDelClientInfo in needDelClientInfoList: g_socketList.remove(needDelClientInfo) if __name__ == '__main__': main()
#coding=utf-8 from socket import * import random import time serverIp = raw_input("请输入服务器的ip:") connNum = raw_input("请输入要链接服务器的次数(例如1000):") g_socketList = [] for i in range(int(connNum)): s = socket(AF_INET, SOCK_STREAM) s.connect((serverIp, 7788)) g_socketList.append(s) print(i) while True: for s in g_socketList: s.send(str(random.randint(0,100))) # 用来测试用 #time.sleep(1)
socket.socket().listen([int<num>])
表示可以同时建立完成的TCP连接数:
服务端代码示例:listen(5) 最多同时建立5个连接,超过5个的部分等待之前建立的断开...
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # @Time: 2020/7/4 12:52 # @Author:zhangmingda # @File: socket_tcp_study.py # @Software: PyCharm # Description:socket 服务端 from socket import * import time # 创建TCP socket tcpSocket = socket(AF_INET,SOCK_STREAM) # 绑定本地地址信息 address = ('',7788) tcpSocket.bind(address) connNum = int(input("请输入listen()的最大连接数:")) # 使用listen监听端口 tcpSocket.listen(connNum) if __name__ == '__main__': while True: # 接收新的客户端来连接服务器 newSocket, clientAddr = tcpSocket.accept() print(clientAddr) time.sleep(1)
客户端:同时发起30个连接建立请求,同时只能建立5个;代码示例如下
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # @Time: 2020/7/4 12:59 # @Author:zhangmingda # @File: socket_tcp_study_client.py # @Software: PyCharm # Description: from socket import * connNum = int(input("请输入要连接服务器的并发数:")) serverAddr = ('127.0.0.1',7788) for i in range(connNum): s = socket(AF_INET,SOCK_STREAM) s.connect(serverAddr) print(i)
输出效果如下:左图(客户端) ;右图(服务端)
socket UDP 发送广播
发送广播设置:setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # @Time: 2020/7/4 14:42 # @Author:zhangmingda # @File: socket_udp_广播.py # @Software: PyCharm # Description: import socket import sys dest_addr = ('<broadcast>', 7788) #创建UDP套接字 s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 设置套接字可以发送广播数据 s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1) # 向网络中所有地址发送广播数据 s.sendto("hi".encode('utf-8'),dest_addr) print("等待对方回复(ctrl + C 退出)") while True: data, address = s.recvfrom(2048) print("Received from %s: %s" % (address,data))
示例UDP客户端聊天小程序
说明:用到了多线程threading.Thread socket
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # @Time: 2020/7/3 18:58 # @Author:zhangmingda # @File: upd聊天模拟客户端.py # @Software: PyCharm # Description:使用UDP协议模拟消息收发 # 功能: # 1、收数据 # 2、同时可以发数据 import socket from threading import Thread class ChatClient(object): """作为一个对象来实现""" def __init__(self,loccal_port,server_ip,server_port): """初始化一个UDP的socket实例 AF_INET 表示网络用IPV4协议 SOCK_DGRAM 表示传输层使用UDP协议 """ self.udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) self.udpSocket.bind(('',loccal_port)) self.serverIP = server_ip self.serverPort = server_port pass def sendData(self): """发数据用方法""" while True: send_str = input("<<:") self.udpSocket.sendto(send_str.encode("gb2312"),(self.serverIP,self.serverPort)) pass def recvData(self): """收数据""" while True: recvData,serverAddress = self.udpSocket.recvfrom(1024) print("\r >>:%s :%s\n<<:" %(str(serverAddress), recvData.decode('gb2312')),end='') pass def main(): localPort = int(input("输入本地端口号:")) server_ip = input("服务器IP:") server_port = int(input("服务器端口:")) # 初始化一个UDPsocket实例 chatclient = ChatClient(localPort,server_ip=server_ip,server_port=server_port) send_thread = Thread(target=chatclient.sendData) recv_thread = Thread(target=chatclient.recvData) send_thread.start() recv_thread.start() send_thread.join() recv_thread.join() if __name__ == '__main__': main()
效果输出
服务端使用“网络调试助手.exe”在windows下模拟
-----------------------------
socketserver并发处理服务端
http://www.cnblogs.com/alex3714/articles/5830365.html
#!/usr/bin/env python # Author:Zhangmingda import socketserver class Mytcphandler(socketserver.BaseRequestHandler): ''' 定义一个socketserver的handler处理类,必须继承socketserver.BaseRequestHandler ''' def handle(self): '''所有的与单个客户端的交互都在此方法''' print('定义自己的socketserver.子handler类hander方法') while True: try: print('客户端IP:{}端口:{}'.format(self.client_address[0], self.client_address[1])) print('等待接收数据...') self.data = self.request.recv(1024) print('收到数据:',self.data.decode()) self.request.sendall(self.data.decode().upper().encode()) except ConnectionResetError as e: print('连接出现错误/客户端已断开:%s'% e) break if __name__ == "__main__": HOST,PORT = 'localhost',6969 print('开启服务,监听端口') server = socketserver.ForkingTCPServer((HOST,PORT),Mytcphandler) #多进程并发 # server = socketserver.ThreadingTCPServer((HOST,PORT),Mytcphandler)#多线程并发 server.serve_forever()
socket客户端
#!/usr/bin/env python # Author:Zhangmingda #!/usr/bin/env python # Author:Zhangmingda import socket print('创建客户端实例') client = socket.socket() print('开始连接服务器') client.connect(('localhost',6969)) while True: msg = input('>>>输入要发送的命令:') print('开始发送数据') client.send(msg.encode('utf-8')) #发送汉子,必须encode()成bytes类型数据进行传输 if msg == '断开': print('关闭数据连接') client.close() break print('开始接受数据') recv_data = client.recv(1024) print('返回数据:',recv_data.decode())
posted on 2018-06-20 14:11 zhangmingda 阅读(238) 评论(0) 编辑 收藏 举报