服务器
- 创建一个服务器代理类TCPServer,其中有init、accept、handle、close函数。
- 在初始化函数中创建socket对象,绑定主机的地址和端口,并将socket变为一个监听套接字。
- accept函数将阻塞工作线程等待客户端的连接(如果你的主线程中还有其他业务逻辑,可以将这个放在子线程中),每拿到一个连接就可以获取到与该客户端的通信套接字,并开辟一个子线程,处理该套接字的业务。
- handle函数就是为每个客户端sockat开辟的线程函数,该函数也会阻塞等待客户端发送数据(当然你也可以使用这个socket对象主动向客户端发送数据)。这里有个机制就是当客户端发送一个空数据就说明与客户端的连接断开了,这个空数据不是空格等没有文本的空。
- close函数中就是关闭TCP服务器的事情了。
import socket
import threading
from org.venus.ocr.src.util import ipUtils
class TCPServer(object):
def __init__(self, port, maxConn):
# 创建TCP服务器
self.tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 解决程序端口占用问题
self.tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定本地ip地址和端口
self.tcpServer.bind(("", port))
# 将套接字变为监听套接字,并设置最大连接数量
self.tcpServer.listen(maxConn)
serverIp = ipUtils.getIp()
print("开启TCP服务器:({0}:{1})".format(serverIp,self.tcpServer.getsockname()[1]))
def accept(self, readBufSize, coding):
# 工作线程,等待客户端连接
while True:
# 等待设备连接(通过ip地址和端口建立tcp连接)
# 如果有设备连接,则会生成用于设备和服务器通讯的套接字:socket
socket, addr = self.tcpServer.accept()
# 会获取到设备的ip地址和端口
print("客户端{0}已连接".format(addr))
# 创建线程处理该连接的业务
handle = threading.Thread(target=self.handle, args=(socket, addr, readBufSize, coding))
handle.start()
def handle(self, socket, addr, readBufSize, coding):
# 客户端业务线程,处理该客户端的通信数据
while True:
# 接收客户端发送的数据,单次最大1024字节,按utf-8格式解码
data = socket.recv(readBufSize).decode(coding)
# 如果设备发送的数据不为空
if data:
print("收到客户端{0}的数据:".format(addr), data)
response = "收到你的数据:" + data
# 返回客户端数据
socket.send(response.encode(coding))
# 如果收到空的数据,说明客户端断开连接
else:
print('客户端{0}断开连接'.format(addr))
break
# 关闭套接字
socket.close()
def close(self):
print("关闭TCP服务器")
self.tcpServer.close()
pass
def run(port):
serverIp = ipUtils.getIp()
if not serverIp:
print("主机没有网络连接")
return
tcpServer = TCPServer(port, 1000)
tcpServer.accept(1024, "utf-8")
# 线程会阻塞在accept函数
tcpServer.close()
if __name__ == '__main__':
run(1991)
客户端
- 创建socket对象,并通过服务器地址和端口连接到服务器中。
- 使用socket对象可以向服务器发送数据和接收数据
这里的测试代码非常简单,就是发送和接收一些数据后就关掉了,在业务中应该是在子线程中使用socket对象一直要接收数据的,并且你也应该手持这个socket对象随时想服务器发送数据,那就是根据业务编码了。
import socket
def run(ip, port, coding, readBufSize):
# 建立一个socket对象
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务器
client.connect((ip, port))
# 定义一个控制变量,这个逻辑仅调试,与业务无关
count = 0
while count < 10:
#使用socket对象向服务器发送数据
sendMsg = "我是Python client 发送的数据" + str(count)
client.send(sendMsg.encode(coding))
#接收服务器响应的数据,如果有的话,因为这里会阻塞
responseMsg = client.recv(readBufSize).decode(coding)
print("收到服务器返回的数据:", responseMsg)
count += 1
client.close()
if __name__ == '__main__':
serverIp = "172.20.10.3"
serverPort = 1991
run(serverIp, serverPort, "utf-8", 1024)
网友评论