• 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("
     >>:%s :%s
    <<:" %(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())

  • 相关阅读:
    double类型的数值计算
    模拟ATM的功能
    自学Java第七周的总结
    自学java第六周的总结
    自学Java第五周的总结
    自学Java第四周的总结
    自学Java第三个星期的总结
    自学Java第二周的总结
    python-----静态方法
    python----类方法
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/9203492.html
Copyright © 2020-2023  润新知