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()
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套接字测试代码对应测试客户端

 

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  阅读(229)  评论(0编辑  收藏  举报

导航