打个标题
我这里是写了一个LPD服务,展示一下socket服务多线程处理,logging日志我另外一篇文章里面有
LPD服务细节我删掉了,不知道什么问题,接收到的socket总是会重复连接接收数据,但这个和socket多线程没有关系的哈
这里要说一下,python里面thread线程启动有两种方法,start()和run()
1、start方法不会造成current线程阻塞
2、run会使用current线程运行将要运行的线程,会阻塞current线程(这个我也说的不是很清楚,反正就是会堵车)
所以如果是想要在创建运行另外的子线程后继续运行主要的代码,要使用start方法启动子线程哦
import sys
import socket
import os
import threading
import time
# 地址簇
socket.AF_INET
socket.AF_INET6
# 套接字类型
socket.SOCK_STREAM # tcp
socket.SOCK_DGRAM # udp
socket.SOCK_RAW # 原始套接字(可伪造IP地址,发起DDOS攻击)
socket.SOCK_RDM # UDP,保证交付,但不保证顺序
socket.SOCK_SEQPACKET
SEND_BUF_SIZE = 4096 # 发送缓冲区的大小
RECV_BUF_SIZE = 4096 # 接收缓冲区的大小
loginfo = log.Logger(filename='./logs/log.log', level='debug',when='D',back_count=10).logger
# ***************
# LPD服务socket相应需要的标识
GOOD_ACK = '\000'.encode('utf-8')
GOOD_ACK2 = '\000\n'.encode('utf-8')
print(GOOD_ACK2)
print(GOOD_ACK)
# ***************
#######################
HOST = '127.0.0.1'
# lpd服务端口
LPDPORT = 515
RAWPORT = 9100
# lpd服务接收的数据保存路径
SAVE_FOLDER = 'C:/'
#######################
DEBUG = False
class LpdThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.name = "LpdThread"
def run(self):
loginfo.info("启动LPD数据服务线程:" + self.name)
StartLpdServer(self.name)
loginfo.info("LPD数据服务线程关闭:" + self.name)
# 启动Lpd服务
def StartLpdServer(mainThreadName):
# 1. 实例化socket对象
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 2. 绑定
server.bind((HOST, LPDPORT)) # 绑定
# 3. 监听链接
server.listen()
loginfo.info("Lpd server start. {0}:{1}".format(HOST,LPDPORT))
threadIndex = 0
while True:
# 4. 接收一个连接
if threadIndex > 10000:
threadIndex = 0
conn, addr = server.accept()
LpdHandlerThread(mainThreadName,threadIndex, conn, time.localtime()).run()
threadIndex = threadIndex + 1
server.close()
# Lpd数据处理线程
class LpdHandlerThread(threading.Thread):
def __init__(self,mainThreadName, name, conn,now):
threading.Thread.__init__(self)
self.mainThreadName = mainThreadName
self.name = name
self.conn = conn
self.now = now
def run(self):
conn = self.conn
# 做想要做的事情
StartLpdHandler(conn,self.now)
loginfo.info("退出线程:{0}{1}".format(self.mainThreadName, self.name))
# Lpd数据处理
def StartLpdHandler(conn,now):
try:
# socket的recv()方法会造成线程堵塞,注意
data_bytes = conn.recv(1024)
conn.send(bytes数据)
except Exception as e:
loginfo.error("job exception" + str(e))
finally:
loginfo.info('数据接收结束,等待连接断开')
if __name__ == "__main__":
try:
LpdThread().start()
except Exception as e:
loginfo.error("Lpd exception" + str(e))