python3环境下的TCP协议与UDP协议的socket编程

来源:互联网 发布:大专学软件开发 编辑:程序博客网 时间:2024/05/16 01:13

最近没事玩玩python,发现python真的是个好东西,开发效率奇高,代码量简洁美观,短小精悍,python的创造者曾申明“要将程序员们从繁重的代码工作中解放出来”,这当然也是python的终极目标,它是比c,c++还有java更高一级的语言,计算机高级语言作为底层机器与人类沟通、交流的一种中介语言,近年来的发展使得它们越来越贴近人类,python就是这其中比较有代表性的一类语言。它的开发效率、简洁度、美观度都是c,c++及java无可比拟的,这是它的特点,也是它的优势。当然语言越高级,越容易被理解固然有它的好处,但是过于远离机器硬件的计算机语言却又会出现运行效率较低的问题, 在这一点上,python确实不及c++与java。毕竟鱼与熊掌不可兼得,我们应该以辩证的观点来看待每一种计算机语言,千万不要走上‘php是世界上最好的语言’这条不归路,当然在这里并不是说php不好,我尊重php的程序员们,我认为在某些领域,php确实有其他所有语言无可替代的优势,但我始终认为各家语言各有千秋,各具优劣。

好了,废话不多说,我们直接进入正题。最近在研究网络编程,本来网络编程应该先去仔细研读那本linux网络编程的经典之作,但是博主在学习这方面却是个速食主义者,我觉得计算机行业的技术更新太快太快,别说要走在时代的前沿,就算能勉强跟上时代的脚步也是很吃力的事情,而且我对于那些不断推层出新的技术有很强的求知欲望,总想将他们一网打尽。虽然自己也知道在对待学术上,这样的态度过于浮躁,还是应该两耳不闻窗外事,一心只撸代码裤。好吧。。目前我还做不到这么淡定,原谅我还年轻好了。

python的网络编程学习起来异常简单,代码神马的一看就明白,这样的话可以把大量的精力放在理解网络编程的原理上面,而不必花太多的时间去研究繁杂的代码细节或者挠完头顶所有的‘头皮屑’去debug,这都是作为搬砖屌丝程序员的我觉得最苦逼的事情。所以我选择python语言来研究网络编程。

网络编程中最重要的两个协议: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
addr=('',51423)
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)                    #SOCK_DGRAM是UDP传输协议
s.bind(addr)

while True:
    data,addr=s.recvfrom(2048)
    print(data)
    if data=='bye':
        print('client has exit')
        break
    print('received:',data," from",addr)
s.close()


#客户端+++++++++++++++++++++++++++++++++++++++++++++++++++++

import socket

addr=('192.168.1.147',51423)
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:
    msg=input()
    s.sendto(msg.encode('utf-8'),addr)
    if msg=='bye':
        break
s.close()

UDP由于是无连接的传输协议,因此这里创建的socket对象不需要调用connnect()方法建立连接,可以直接使用sendto()和recvfrom()来发送和接收数据。UDP协议并不可靠,发送端不知道接受端有没有收到数据,发送端就只在发送的时候发送一次数据,如果网络拥塞很有可能造成接收端没有正常接收到数据。TCP连接会多次重发数据,直到接收到来自接收方的回送消息为止。

怎么样?python的网络编程是不是异常的简洁,区区几十行代码就轻松实现了基本的TCP和UDP协议的C/S通信,所以我觉得用python语言来深入研究网络编程的原理还是很不错的选择,对网络编程感兴趣但是又还没入门的朋友可以试试哟!

0 0
原创粉丝点击