Python学习记录6——Socket网截模块的应用

Python学习记录4——在Ubuntu下使用Pycharm,被官方和谐了。

一.网截模块的简单应用

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 这就创建了一个服务端
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 设置端口复用,结束后能快速再打开
server.bind(('0.0.0.0', 12345))  # 绑定监听的ip和端口,ip可以修改为本地127.0.0.1
server.listen(120)  # 最大接收客户端数量为120

while True:  # 死循环监听
    client, addr = server.accept()
    recv_data = client.recv(1024).decode('utf-8')  # 接收消息,最大字节数,编码
    client.close() #收到消息 结束通讯
    print(recv_data,addr)
server.close()

二.多线程接收(建议不使用)

这种虽然能接收多个客户端的消息,但是,它的发送只会发送给最新的客户端,而且一旦一个客户端断开连接,所有的客户端都会断开连接,如果不断连接,那么还有一个空线程在运行,总之,不建议使用。

import socket
import threading
address='127.0.0.1'     #监听哪些网络  127.0.0.1是监听本机 0.0.0.0是监听整个网络
port=12345             #监听自己的哪个端口
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((address,port))
server.listen(2)     #最大连接数

def tcplink(sock,addr):#单个线程获取数据
    while True:
        redata=clientsock.recv(2048).decode('utf-8')
        if redata == "": #当用户退出时,会得到一个空消息
            break
        print(redata)
        clientsock.close()
    clientsock.close()
    
while True:
    clientsock,clientaddress=server.accept()
    t=threading.Thread(target=tcplink,args=(clientsock,clientaddress))  #创建的线程t
    t.start() #启动线程
server.close()

三.真·多线程并发接收

因为经过我的测试,二中的代码并不能有效的进行接收,即使是多线程的,它也是个伪并发接收,我们需要修改模块,使用我们TCP通信的专属服务端模块 python自带的 socketserver模块

  • 创建一个继承自"socketserver.BaseRequestHandler"的类,重写类方法handle.
  • 当收到tcp连接时,会自动创建线程来运行handle,一旦handle运行完毕,这个线程就会被销毁,所以需要使用死循环来一直保持与客户端的连接,直到客户端主动退出,再break出循环。
  • 使用ThreadingTCPServer函数,创建实例,并传递参数。
  • 使用运行serve_forever(),运行实例,并永远运行除非发生异常。这模块也挺好的,用try把handle包起来的,也减小了意外发生。

代码:

import socketserver

class SockServer(socketserver.BaseRequestHandler):

    def handle(self):
        request = self.request
        request.sendall("welcome to the tcp server\r\n".encode('utf-8'))
        while True:
            data = request.recv(1024).decode('utf-8')
            if data == '': #当tcp服务端收到一个空消息的时候,相当于客户端主动退出
                print(self.client_address)
                print("断开与%s的连接"%(self.client_address, )) #注意这个, 因为client_address是一个二元组
                break
            else:
                print("收到%s的消息:\r\n%s"%(self.client_address,data))
                request.sendall('server got your message\r\n'.encode('utf-8'))

if __name__ == '__main__':
    tcp_server = socketserver.ThreadingTCPServer(('0.0.0.0', 12345), SockServer)
    print('启动服务器!')
    tcp_server.serve_forever()

四.发送

发送没写,但是看socket的代码就很容易知道怎么写。或者搜索其他人的文章也行。

发布了63 篇原创文章 · 获赞 38 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/u011017694/article/details/104134969