这里写自定义目录标题
Python 服务端步骤以及代码
大家好! 本文是来介绍一下如何在Python+PyCharm下编写TCP服务端的步骤以及注意事项,并且我是一个Python初学者(之前博主主要工作写C#,已经三年时间了),我在编写代码的过程中遇到的问题如何解决。
效果以及实现的功能
TCP Server服务端主要是与客户端互相发送消息为主要目的,还有接收多个客户端发送过来的消息。
以下是用PyCharm编写出来的效果
了解TCP的内部工作过程
TCP握手协议
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
SYN:同步序列编号(Synchronize Sequence Numbers)
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手.
完成三次握手,客户端与服务器开始传送数据
详情可看另一博主的详细解说,我这里就不详细解说了
https://www.cnblogs.com/Qing-840/p/9283367.html
首先编写简单UI界面
在UI界面方面我是使用了PyQt5来编写界面,因为PyQt5目前对于以下简单的界面只是需要往页面里面拖动控件就可以完成了。设置一下各个控件的命名。
界面元素很简单:
1.IP地址,端口地址(必须要有)
2.监听按钮(Listen)
3.消息框
4.Client选择框ComboBox+输入框+发送Button
转换成PY文件(就是界面文件)
只需要使用外部工具pyuic5_32就可以转换成PY文件。
TCP 服务端初始化(即Socket初始化)
需要有4个步骤
1.设置端口与IP地址
2.建立Socket对象
3.绑定IP地址与端口,以及设置监听最大连接数
4.建立监听线程
以下是代码
#导入类库-线程+Socket类库
import socket
import threading
#获取IP地址以及端口号
addr = self.txtAddr.toPlainText()
port = int(self.txtPort.toPlainText())
self.ip_port = (addr,port) #('127.0.0.1',8080)
#建立Socket对象以及设置相关参数
self.tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#绑定IP端口
self.tcpServer.bind(self.ip_port)
#设置最大监听数量
self.tcpServer.listen(5)
#开启监听线程-防止线程阻塞
thListen = threading.Thread(target=self.ListenProc,args=())
thListen.setDaemon(True)
thListen.start()
编写监听函数
步骤:
1.获取已经握手成功的对象。
2.开启接收消息线程。
#利用while 持续监听-此处需要放置在多线程里面或者使用异步方法,防止界面假死。
while True:
client_socket,ip_port = self.tcpServer.accept() #接受连接,获取连接对象
if client_socket:
#添加到列表,方便发送数据是寻找
self.clist_list.append(client_socket)
self.cboAddr.addItem(str(ip_port))
self.txtMsg.append('Connect device'+str(ip_port))
#开启接收线程,实时接收多个客户端所发送的消息
thClient = threading.Thread(target=self.ReceiveProc,args=(client_socket, ip_port))
thClient.setDaemon(True)
thClient.start()
编写接收函数
重点是client_socket.recv(),此函数用于接收数据
# 接收线程
def ReceiveProc(self,client_socket, ip_port):
while True:
try:
if client_socket:
client_msg = client_socket.recv(1024)
if client_msg:
#显示到textBox
self.txtMsg.append('[Client Msg]'+str(ip_port)+':'+client_msg.decode("gbk"))
except ConnectionResetError:
client_socket.close()
except:
self.txtMsg.append('Receive Msg Error!')
发送函数
def BtnSendMsg(self):
data = str(self.txtSend.toPlainText())
index = self.cboAddr.currentIndex()
buffer = bytes(data, encoding="utf-8")
#使用sendall函数,此函数只是支持byte类型所以需要注意转换
self.clist_list[index].sendall(buffer)
上述为主要的代码,以及解释,详细在我博客内。