版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ykiwmy/article/details/78768970
网络编程中最重要的两个协议:TCP协议和UDP协议
TCP协议是互联网中使用最广泛的传输协议,这得益于其稳定,可靠的优势。TCP协议是面向连接的传输协议,通信双方(通常是两个主机上面的两个程序)需要先建立连接,才能传输数据。数据在传输过程中会被分成多个小的数据包,这些数据包都会被添加上序号,全部达到接收端的小数据包会根据这些序号重新拼凑起来。TCP传输的数据包加入了检验码,可以检测在传输过程中数据包是否被更改过,对于更改过或者损失了数据的数据包,接收端会要求发送端重新发送。接收端在收到发送端发送的数据包之后,会回送一个消息到发送端,告诉发送端已经安全接收到数据包了,如果发送端没有收到这个回送消息,则会经过一段时间再次发送该数据包。因此在这种协议下面,数据的传输是十分稳定可靠的。
UDP协议是一类无连接的传输协议。发送端只管将数据发送出去,接收端收到数据后也不会发送回送消息给发送端,因此发送端并不知道接收端有没有收到完整的数据。TCP需要的时间和系统开销都比UDP大,UDP在传输一些小数据时有一定的优势,通常来说UDP一次传输的数据大小不能超过64kb,一般来说最佳的数据大小是<1kb。
python3可以使用socket模块简单的实现TCP与UDP传输协议,下面看服务器和客户端代码
TCP传输的python3代码:
#服务器端代码++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#/usr/bin/env python
import
socket
import
time
host
=
''
port
=
51423
bufsize
=
1024
addr
=
(
host
,
port
) #host设定为空,表示可以与任何ip的socket在端口51423通信
#设置socket,AF_INET表示是IPV4标准,SOCK_STREAM是TCP传输协议
tcpSerSock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
tcpSerSock
.
bind
(
addr
)
tcpSerSock
.
listen
(
1
)
quit
=
False
shutdown
=
False
while
True
:
print
(
'waiting for connection...'
)
tcpCliSock
,
addr
=
tcpSerSock
.
accept
() #不断监听获取新的客户端连接
print
(
'...connected from:'
,
addr
)
while
True
: #与客户端建立连接之后,获取客户端传来的数据
data
=
tcpCliSock
.
recv
(
bufsize
)
data
=
data
.
decode
(
'utf-8'
)
if
not
data
:
break
ss
=
'[
%s
]
%s
'
%
(
time
.
ctime
(),
data
)
tcpCliSock
.
sendall
(
ss
.
encode
(
'utf-8'
))
print
(
ss
)
if
data
==
'bye'
:
quit
=
True
break
elif
data
==
'shutdown'
:
shutdown
=
True
break
print
(
'Bye-bye:[
%s
:
%d
]'
%
(
addr
[
0
],
addr
[
1
]))
tcpCliSock
.
close
()
if
shutdown
:
break
tcpSerSock
.
close
()
print
(
'Server has been closed'
)
#客户端代码+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import
socket
host
=
'192.168.1.147'
port
=
51423
bufsize
=
1024
addr
=
(
host
,
port
)
tcpCliSock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
tcpCliSock
.
connect
(
addr
)
while
True
:
data
=
input
(
'>'
)
if
not
data
:
continue
print
(
'input data:[
%s
]'
%
data
)
tcpCliSock
.
sendall
(
data
.
encode
(
'utf-8'
))
rdata
=
tcpCliSock
.
recv
(
bufsize
)
if
not
rdata
:
break
print
(
rdata
.
decode
(
'utf-8'
))
if
data
==
'bye'
or
data
==
'shutdown'
:
break
首先启动服务器代码,然后在启动客户端代码,这样服务器与客户端就建立了连接。在客户端控制台输入的数据会在服务器控制台显示出来。客户端输入'bye'字符时,服务器会关闭客户端的socket连接,客户端输入'shutdown'时,服务器关闭客户端和服务器端的socket连接。
测试代码时最好能用两台电脑测试。也可以像博主一样在一台电脑上面装一个虚拟机操作系统,使用桥接模式,也可以模拟客户端和服务器端完成端到端测试。
UDP传输的python代码:
#服务器端++++++++++++++++++++++++++++++++++++++++++++++++
import socket
BUFF_SIZE = 1024
server_addr = ('127.0.0.1', 55555)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # SOCK_DGRAM是UDP传输协议
s.bind(server_addr)
print('bind ok!')
while True:
data, addr = s.recvfrom(BUFF_SIZE)
print(data)
if data is 'bye':
print('client has exit')
break
print('received:', data, " from", addr)
s.close()
#客户端+++++++++++++++++++++++++++++++++++++++++++++++++++++
import socket
server_addr = ('127.0.0.1', 55555)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
msg = input('>')
print(msg)
s.sendto(msg.encode('utf-8'), server_addr)
if msg is 'bye':
break
s.close()
UDP由于是无连接的传输协议,因此这里创建的socket对象不需要调用connnect()方法建立连接,可以直接使用sendto()和recvfrom()来发送和接收数据。UDP协议并不可靠,发送端不知道接受端有没有收到数据,发送端就只在发送的时候发送一次数据,如果网络拥塞很有可能造成接收端没有正常接收到数据。TCP连接会多次重发数据,直到接收到来自接收方的回送消息为止。