socket模块实现基于UDP聊天模拟程序;socketserver模块实现服务端 socket客户端代码示例
阅读原文时间:2023年07月08日阅读:2

socket模块

#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()

socket.socket().setblocking(False)

#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)

非阻塞TCP套接字测试代码对应测试客户端

表示可以同时建立完成的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)

输出效果如下:左图(客户端)   ;右图(服务端)

发送广播设置: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 = ('', 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))

说明:用到了多线程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下模拟

-----------------------------

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())