Python 之开启 socket 服务,允许多个用户同时连接

前几天公司有个业务,需要用 Python 在服务器上搭建一个 socket 服务,与 Django 开发的系统配合使用。
那么问题来了, 如果单纯地使用 socket 来搭建一个服务,如果用户访问页面,socket 开启的端口就会被占用,也就是说,一次只能运行一个连接。

那么如何实现允许多个用户同时连接到这个 socket 服务呢,网上找了一些方法,其中我觉得较为简单和熟悉的一种就是使用多线程。

以下是简单的代码框架:

	from socket import *
	import _thread
	
    HOST = ""
    PORT = 8588
    BUFSIZ = 1024    #缓冲区大小
    ADDR = (HOST,PORT)
    tcpSerSock = socket(AF_INET,SOCK_STREAM)
    tcpSerSock.bind(ADDR)
    tcpSerSock.listen(60)    #连接被转接或者被拒绝之前,传入连接请求的最大数
    while True:
        tcpCliSock, addr = tcpSerSock.accept()
        print("waiting for connect ...")
        print("...connect from:", addr)
        _thread.start_new_thread(getData, (tcpCliSock, ))
        continue

其中,关于 socket 第三方库的使用方法就不多说了,提请注意的一点是 _thread 这个库。

_thread:
在 Python3 版本中,只有 threading 这个库了,但是为了兼容废弃的 thread 这个库,就搞了个这个库出来,在这里用到的方法还算简单,但推荐的还是使用 threading 这个库,说不定哪天改版又被兼容和废弃了。

_thread.start_new_thread(func, (arg1,))

这样就算开启了一个新的线程,函数和参数的调用方法和 threading 是一样的,多线程这个方法很有用,打算以后有时间可以简单梳理一下,在这里知道这样调用就 OK 了。

线程报错的问题:
首先说一下这个 socket 服务的主要内容,是通过用户连接,然后传输一些字节的信息,信息分为两部分,一部分是头部信息,一部分是主体信息。

头部信息长度是固定的,会包含整个信息的长度之类的内容;
主体信息则是我们需要获取的信息内容。
在解析这些信息的时候,我们会用到 Python 的第三方库叫做 struct ,这个库用来 pack 和 unpack tcp 传输过来的信息,这是一个很重要的 第三方库,mark 下,以后还会详细介绍它,但不是今天的重点。
重点是,在我们这个获取的函数里,发生了报错怎么办?

最开始的我的函数是这样写的:

def getData(tcpCliSock):
    while True:
		doing something
    tcpCliSock.close()
	_thread.stop()

在函数内部,一旦报错,跟踪的实时流就会卡在报错的地方不再动了。
但这不是我们想要的,所以,在这个函数里面,加了个 try except 来获取报错,并进行处理,退出这个 while 循环。

def getData(tcpCliSock):
    while True:
        try:
			doing something
        except:
            break
    tcpCliSock.close()
    _thread.stop()

如果需要记录,在 except 里面还可以加上日志的记录。
然后,关掉这个打开的 socket 连接,关掉这个线程。

整个代码流程如下:

from socket import *
import _thread
def getData(tcpCliSock):
    while True:
        try:
			doing something
        except:
            break
    tcpCliSock.close()
    _thread.stop()

if __name__ == '__main__':
    HOST = ""
    PORT = 8588
    BUFSIZ = 1024    #缓冲区大小
    ADDR = (HOST,PORT)
    tcpSerSock = socket(AF_INET,SOCK_STREAM)
    tcpSerSock.bind(ADDR)
    tcpSerSock.listen(60)    #连接被转接或者被拒绝之前,传入连接请求的最大数
    while True:
        tcpCliSock, addr = tcpSerSock.accept()
        print("waiting for connect ...")
        print("...connect from:", addr)
        _thread.start_new_thread(getData, (tcpCliSock, ))
        continue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值