TCP协议通信
tcp通信协议是一种面向连接的,可靠的数据传输协议。通常应用在对网络信息传输准确性要求较高的情形,比如文件传输,聊天信息传输等等。
在TCP通信过程中,核心的过程是经过三次握手建立连接和四次挥手断开连接。
三次握手的过程:1、客户端(client)向服务器端(server)发出请求,请求建立连接;2、服务器端收到请求后确认,并给客户端返回报文,同意建立连接;3、客户端收到许可请求,建立连接。
四次挥手:1、主动方发送报文给被动方请求断开连接;2、被动方收到断开请求后返回报文给主动方,已经收到断开请求,开始准备断开连接;3、被动方再次给主动方发送报文,可以断开连接;4、主动方发送报文确定断开。
Tips:在三次握手建立连接的过程中,通常都是客户端发起请求,服务器端确认请求。而四次挥手断开连接时,不管是客户端还是服务器端都可以发起断开的请求。
使用TCP协议编程,是用到了python的socket模块。socket俗称套接字,是一种网络通信的方式。使用这个模块编程,我们不用关注信息在网络中各个层级之间是怎样传输的,只需要使用socket模块的方法和属性建立连接并发送信息即可。
下面通过一个示例介绍socket模块中常用的方法和属性。
#TCP传输协议的server端
from socket import *
sockfd = socket(AF_INET,SOCK_STREAM,0)
sockfd.bind(('127.0.0.1',8888))
sockfd.listen(5)
while True:
connfd,addr = sockfd.accept()
while True:
data = connfd.recv(1024)
if not data:
break
print(data.decode())
connfd.send('收到了你的信息啦!'.encode())
connfd.close()
sockfd.close()
程序解读:
1、首先导入使用的socket包,建议使用上面方法导入。
from socket import * #可以将socket包中所有的函数全部导入
2、创建套接字
s = socket(socket_family=AF_INET, socket_type=SOCK_STREAM,proto = 0)
s:创建的套接字对象
socket:创建套接字的函数
AF_INET,本地通信时使用AF_UNIX。
socket_type:套接字类型,使用TCP通信时会创建流式套接字(SOCK_STREAM)
使用UDP通信时创建数据报套接字(SOCK_DGRAM)
proto:子协议类型,默认为0,参数可以省略
Tips:在创建套接字时,按照上面的方式即可,或者直接使用s = socket()语句,默认创建的是流式套接字,但是在创建数 据报套接字时,必须要写参数,s = socket(AF_INET,SOCK_DGRAM)
3、绑定端口号和IP
s.bind('127.0.0.1',8888)
Tips:参数是一个元组,元组中第一项是IP,第二项是端口,也可以写成如下方式:
ADDR = ('127.0.0.1',8888)
s.bind(ADDR)
4、让套接字变为监听套接字
s.listen(5)
此函数能够将前面创建的套接字对象变为监听套接字,其中参数5是监听队列的大小,可以最多接入5个客户端
5、阻塞等待客户端连接
c,addr = s.accept()
此函数的返回值是一个数组,数组第一项是一个新的套接字,用来进行通信(前面创建的套接字s只是用来连接客户端,而新创建的套接字c是用来和客户端传递消息的),数组第二项是连入的客户端的地址
6、发送和接收消息
c.send(data)
发送消息,data是发送的内容,如果data是字符串,需要转换成二进制编码再发送,参考上面程序
d = c.recv(buffersize)
接受消息。buffersize是一次接受消息的大小(byte)。d是接收到消息的内容,也是二进制格式,要转换为字符串显示
7、关闭套接字
s.close()
下面是客户端的程序
#TCP传输协议的客户端
from socket import *
sockfd = socket(AF_INET,SOCK_STREAM)
sockfd.connect(('127.0.0.1',8888))
while True:
msg = input("发消息>>")
sockfd.send(msg.encode())
if not msg:
break
data = sockfd.recv(1024)
print(data.decode())
sockfd.close()
程序详解:
1、导入socket包;
2、创建流式套接字
3、建立连接
sockfd.connect('127.0.0.1',8888)
参数与server端的bind函数一样,也是一个元组。客户端连接的IP、端口要和服务器端绑定的IP、端口一致
4、消息收发
5、关闭套接字