PythonTCP协议网络编程学习笔记
TCP协议介绍TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP) TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP通信需要经过创建连接、数据传送、终止连接三个步骤。 TCP通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,"打电话",而UDP类似于生活中的"发短信"。
TCP三次握手首先Client(客户)端发送连接请求报文(第一次握手)。 Server(服务器)端接受连接后回复ACK报文(第二次握手),并为这次连接分配资源。 Client端接收到ACK报文后也向Server段发生ACK报文(第三次握手),并分配资源,这样TCP连接就建立了。
详细三次握手过程如下:
第一次握手:起初两端都处于CLOSED关闭状态,Client将标志位SYN置为1,随机产生一个值seq=x,并将该数据包发送给Server,Client进入SYN-SENT状态,等待Server确认;
第二次握手:Server收到数据包后由标志位SYN=1得知Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1,随机产生一个值seq=y,并将该数据包发送给Client以确认连接请求,Server进入SYN-RCVD状态,此时操作系统为该TCP连接分配TCP缓存和变量;
第三次握手:Client收到确认后,检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=y+1,并且此时操作系统为该TCP连接分配TCP缓存和变量,并将该数据包发送给Server,Server检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client和Server就可以开始传输数据。
TCP四次挥手
客户端主动发起请求,服务端被动关闭。
首先是client向server发起断开连接请求,server响应client等会儿断开,server响应client可以断开了,client告知server已经断开链接。
详细过程如下:
第一次挥手:起初client和server处于ESTABLISHED状态——client发出连接释放报文段并处于FIN-WAIT-1状态
第二次挥手:server发出确认报文段且进入CLOSE-WAIT状态——A收到确认后。
第三次挥手:client进入FIN-WAIT-2状态,等待server的连接释放报文段。
第四次挥手:server没有要向client发出的数据,server就发出连接释放报文段且进入LAST-ACK状态——client发出确认报文段且进入TIME-WAIT状态——server收到确认报文段后进入CLOSED状态——client经过等待计时器时间2MSL后,进入CLOSED状态。
TCP服务端创建流程socket创建一个套接字 bind绑定ip和port listen使套接字变为可以被动链接 accept等待客户端的链接 recv/send接收发送数据 1server.py文件内容如下: 2 3from socket import socket,SOCK_STREAM,AF_INET #导入模块 4def tcp_server(): 5 tcp_server_socket=socket(AF_INET,SOCK_STREAM) #创建TCP服务端套接字对接,UDP是SOCK_DGRAM 6 server_address=("127.0.0.1",8888)#定义本TCP服务端的ip and port 7 tcp_server_socket.bind(server_address) #绑定本机的8888端口 8 tcp_server_socket.listen() #执行监听 9 client_socket,client_info = tcp_server_socket.accept() #接收客户端的socker and info 10 data=client_socket.recv(1024)#接收客户端发过来的消息 11 print("the data is:%s, it"s from %s",(client_info,data.decode("utf-8")))#打印客户端的消息 12 client_socket.close()#关闭客户端的连接 13 tcp_server_socket.close()#关闭服务端的连接 14 15if __name__ == "__main__": 16 print("the TCP server is running ...") 17 tcp_server() 18 19 20 21client.py文件内容如下: 22from socket import socket,SOCK_STREAM,AF_INET #导入模块 23def tcp_client(): 24 tcp_client_socket=socket(AF_INET,SOCK_STREAM) #创建TCP客户端套接字对接 25 server_address=("127.0.0.1",8888)#定义本TCP服务端的ip and port 26 tcp_client_socket.connect(server_address) #连接到服务端 27 message="hello my name is tony" #定义要发送的消息 28 tcp_client_socket.send(message.encode("utf-8"))#向服务端发送消息 29 tcp_client_socket.close()#关闭客户端的连接 30 31 32if __name__ == "__main__": 33 print("the TCP client is running ...") 34 tcp_client() 35 print("the message was send")
输出内容为:1#server.py文件输出内容如下: 2the TCP server is running ... 3the data is:%s, it"s from %s (("127.0.0.1", 50929), "hello my name is tony") 4 5 6#client.py文件输出内容如下: 7the TCP client is running ... 8the message was send
改进上面代码使Server和Client可以互相交流沟通,server.py与client.py文件内容是具体的实现代码。 server.py文件内容: 1from socket import socket,SOCK_STREAM,AF_INET #导入模块 2def tcp_server(): 3 tcp_server_socket=socket(AF_INET,SOCK_STREAM) #创建TCP服务端套接字对接,UDP是SOCK_DGRAM 4 server_address=("127.0.0.1",8888)#定义本TCP服务端的ip and port 5 tcp_server_socket.bind(server_address) #绑定本机的8888端口 6 tcp_server_socket.listen() #执行监听 7 client_socket,client_info = tcp_server_socket.accept() #接收客户端的socker and info 8 while 1: 9 data=client_socket.recv(1024)#接收客户端发过来的消息 10 print("the client say:",data)#打印客户端发送过来的信息 11 server_answer=input(">>>")#从键盘录入信息 12 client_socket.send(server_answer.encode("utf-8")) 13 14if __name__ == "__main__": 15 print("the TCP server is running ...") 16 tcp_server()
步骤如下: 导入模块 建立TCP socket连接 绑定ip 和 port 启动监听 等待accept 一直循环接收客户端的请求 打印客户端的消息 输入消息并回复给客户端 client.py文件内容: 1from socket import socket,SOCK_STREAM,AF_INET #导入模块 2def tcp_client(): 3 tcp_client_socket=socket(AF_INET,SOCK_STREAM) #创建TCP客户端套接字对接 4 server_address=("127.0.0.1",8888)#定义本TCP服务端的ip and port 5 tcp_client_socket.connect(server_address) #连接到服务端 6 while 1: 7 message=input("client>>>") #定义要发送的消息 8 tcp_client_socket.send(message.encode("utf-8"))#向服务端发送消息 9 response=tcp_client_socket.recv(1024) 10 print("the server say:",response.decode("utf-8")) 11 12if __name__ == "__main__": 13 print("the TCP client is running ...") 14 tcp_client() 15 print("the message was send")
步骤如下: 导入模块 建立TCP socket连接 连接到服务端监听的ip 和 port 一直循环输入消息并发送给服务端 接收服务端返回的消息 打印服务端返回的消息 Server and Client 对应的输出:1client console output: 2the TCP client is running ... 3client>>>hello tony 4the server say: hello jack 5client>>>how are you 6the server say: i"m fine 7client>>> 8 Server Console 对应的输出:1the TCP server is running ... 2the client say: b"hello tony" 3>>>hello jack 4the client say: b"how are you" 5>>>i"m fine
增加当服务器重启后客户端不挂掉,客户端能够重试连接服务端的功能。
代码实现如下:
server.py文件内容如下 1from socket import socket,SOCK_STREAM,AF_INET #导入模块 2 3def tcp_server(): 4 tcp_server_socket=socket(AF_INET,SOCK_STREAM) #创建TCP服务端套接字对接,UDP是SOCK_DGRAM 5 server_address=("127.0.0.1",9999)#定义本TCP服务端的ip and port 6 tcp_server_socket.bind(server_address) #绑定本机的9999端口 7 tcp_server_socket.listen() #执行监听 8 client_socket,client_info = tcp_server_socket.accept() #接收客户端的socker and info 9 while 1: 10 data=client_socket.recv(1024)#接收客户端发过来的消息 11 datas=data.decode("utf-8") 12 if(len(datas)>1): 13 print("the client say:",datas)#打印客户端发送过来的信息 14 if(datas=="bye"): 15 break 16 server_answer=input(">>>")#从键盘录入信息 17 client_socket.send(server_answer.encode("utf-8")) 18 19if __name__ == "__main__": 20 print("the TCP server is running ...") 21 tcp_server()
client.py文件内容如下 1import time 2 3from socket import socket,SOCK_STREAM,AF_INET #导入模块 4 5 6def connection_socket(): 7 tcp_client_socket = socket(AF_INET, SOCK_STREAM) # 创建TCP客户端套接字对接 8 server_address = ("127.0.0.1", 9999) # 定义本TCP服务端的ip and port 9 try: 10 tcp_client_socket.connect(server_address) # 连接到服务端 11 except: 12 print("connection failed!!!") 13 exit(0) 14 return tcp_client_socket 15 16def tcp_client(): 17 while 1: 18 try: 19 tcp_client_socket=connection_socket() 20 message=input("client>>>") #定义要发送的消息 21 print("the message is:",message) 22 print(tcp_client_socket) 23 tcp_client_socket.send(message.encode("utf-8"))#向服务端发送消息 24 response=tcp_client_socket.recv(1024) 25 print("the server say:",response.decode("utf-8")) 26 except: 27 tcp_client_socket.close()#关闭原有socket连接 28 print("the socket connection is failed, try again to reconnection...") 29 time.sleep(3) 30 31if __name__ == "__main__": 32 print("the TCP client is running ...") 33 tcp_client() 34 print("the message was send")
client console output: 1the TCP client is running ... 2 3client>>>abc 4the message is: abc 5 6the server say: def 7 8client>>>aa 9the message is: aa 10 11the socket connection is failed, try again to reconnection... 12 13client>>>abc 14the message is: abc 15 16the server say: def 17client>>>