【python网络编程】创建TCP/UDP服务器进行客户端/服务器间通信


客户端/服务器网络编程介绍

软件服务器也运行在一块硬件之上,但是没有像硬件服务器那样的专用外围设备(如打印机、磁盘驱动器等)。软件服务器提供的主要服务包括程序执行、数据传输检索、聚合、更新,或其他类型的编程或数据操作。
现在一个更常见的软件服务器就是Web 服务器。如果个人或公司想要运行自己的Web 服务器,那么必须拥有一台或多台计算机,在上面安装希望提供给用户的Web 页面和Web 应用程序,然后启动Web 服务器。一个这样的服务器的工作就是接受客户端请求,并向(Web)客户端(即用户计算机上的浏览器)回送Web 页面,然后等待下一个客户端的请求。这些服务器一旦开启,都将可能永远运行。虽然它们并不能实现这一目标,但是它们会尽可能长时间地运行,除非受到一些外力驱使才会停止,如显式地关闭,或灾难性地关闭(由于硬件故障)。
数据库服务器是另一种类型的软件服务器。它们接受客户端的存储或检索请求,响应请求,然后等待更多的事务。与Web 服务器类似,它们也是永远运行的。

在服务器响应客户端请求之前,必须进行一些初步的设置流程来为之后的工作做准备。
首先会创建一个通信端点,它能够使服务器监听请求。可以把服务器比作公司前台,或者应答公司主线呼叫的总机接线员。一旦电话号码和设备安装成功且接线员到达时,服务就可以
开始了。

套接字:通信端点

套接字是计算机网络数据结构,它体现了上节中所描述的“通信端点”的概念。在任何类型的通信开始之前,网络应用程序必须创建套接字。可以将它们比作电话插孔,没有它将无法进行通信。
套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个进程)与另一个运行的程序进行通信。这就是所谓的进程间通信(Inter Process Communication,IPC)。有两种类型的套接字:基于文件的和面向网络的。

1.面向连接的套接字
不管你采用的是哪种地址家族,都有两种不同风格的套接字连接。第一种是面向连接的,这意味着在进行通信之前必须先建立一个连接,例如,使用电话系统给一个朋友打电话。这
种类型的通信也称为虚拟电路或流套接字。
面向连接的通信提供序列化的、可靠的和不重复的数据交付,而没有记录边界。这基本上意味着每条消息可以拆分成多个片段,并且每一条消息片段都确保能够到达目的地,然后将它们按顺序组合在一起,最后将完整消息传递给正在等待的应用程序。
实现这种连接类型的主要协议是传输控制协议(更为人熟知的是它的缩写TCP)。为了创建TCP 套接字,必须使用SOCK_STREAM 作为套接字类型。TCP 套接字的名字
SOCK_STREAM 基于流套接字的其中一种表示。因为这些套接字(AF_INET)的网络版本使用因特网协议(IP)来搜寻网络中的主机,所以整个系统通常结合这两种协议(TCP 和IP)来进行(当然,也可以使用TCP 和本地[非网络的AF_LOCAL/AF_UNIX]套接字,但是很明显此时并没有使用IP)。

2.无连接的套接字
与虚拟电路形成鲜明对比的是数据报类型的套接字,它是一种无连接的套接字。这意味着,在通信开始之前并不需要建立连接。此时,在数据传输过程中并无法保证它的顺序性、可靠性或重复性。然而,数据报确实保存了记录边界,这就意味着消息是以整体发送的,而并非首先分成多个片段,例如,使用面向连接的协议。
使用数据报的消息传输可以比作邮政服务。信件和包裹或许并不能以发送顺序到达。
事实上,它们可能不会到达。为了将其添加到并发通信中,在网络中甚至有可能存在重复的消息。
既然有这么多副作用,为什么还使用数据报呢(使用流套接字肯定有一些优势)?由于面向连接的套接字所提供的保证,因此它们的设置以及对虚拟电路连接的维护需要大量的开销。
然而,数据报不需要这些开销,即它的成本更加“低廉”。因此,它们通常能提供更好的性能,并且可能适合一些类型的应用程序。
实现这种连接类型的主要协议是用户数据报协议(更为人熟知的是其缩写UDP)。为了创建UDP 套接字,必须使用SOCK_DGRAM 作为套接字类型。
为了创建TCP/IP 套接字,可以用下面的方式调用socket.socket()。
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
同样,为了创建UDP/IP 套接字,需要执行以下语句。
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

服务器套接字方法
s.bind() 将地址(主机名、端口号对)绑定到套接字上
s.listen() 设置并启动TCP 监听器
s.accept() 被动接受TCP 客户端连接,一直等待直到连接到达(阻塞)

客户端套接字方法
s.connect() 主动发起TCP 服务器连接
s.connect_ex() connect()的扩展版本,此时会以错误码的形式返回问题,而不是抛出一个异常
普通的套接字方法

s.recv()接收TCP 消息
s.recv_into()① 接收TCP 消息到指定的缓冲区
s.send()发送TCP 消息
s.sendall()完整地发送TCP 消息
s.recvfrom()接收UDP 消息
s.recvfrom_into()接收UDP 消息到指定的缓冲区
s.sendto()发送UDP 消息
s.getpeername()连接到套接字(TCP)的远程地址
s.getsockname()当前套接字的地址
s.getsockopt()返回给定套接字选项的值
s.setsockopt()设置给定套接字选项的值
s.shutdown()关闭连接
s.close()关闭套接字
s.detach()在未关闭文件描述符的情况下关闭套接字,返回文件描述符

实例:客户端发送数据,接收服务器返回的时间戳

服务端:

from socket import *
from time import ctime
#创建一个TCP 服务器,它接受来自客户端的消息,并返回加了时间戳前缀的相同消息。
host=''
port=21567
bufsiz=1024
addr=(host,port)
tcpServer=socket(AF_INET,SOCK_STREAM)
tcpServer.bind(addr)
tcpServer.listen(5)
while True:
    print('wait for connection..')
    tcpCliServer,addr= tcpServer.accept()
    print('..connect from',addr)
    while True:
        data = tcpCliServer.recv(bufsiz).decode()
        if not data:
            break
        #tcpCliServer.send('[%s]%s' % (bytes(ctime(),'utf-8'),str.encode(data)))
        tcpCliServer.send(bytes(ctime(), 'utf-8'))
    tcpCliServer.close()

tcpServer.close()

客户端:


from socket import *
host='localhost'
port=21567
bufsize=1024
addr=(host,port)
tcpClient=socket(AF_INET,SOCK_STREAM)
tcpClient.connect(addr)
while True:
    data=input('>')
    if not data:
        break
    tcpClient.send(str.encode(data))
    data=tcpClient.recv(bufsize)
    if not data:
        break
    print(data)
tcpClient.close()

结果:

在这里插入图片描述
主要注意点是在编码和解码上。

若要创建UDP服务器只要将参数改为UdpServer=socket(AF_INET,SOCK_DGRAM)即可

用Python 编写FTP 客户端程序

文件传输协议(File Transfer Protocol,FTP)于1985 年10 月发布。FTP 主要用于匿名下载公共文件,也可以用于在两台计算机之间传输文件,特别是在使用Windows 进行工作,而文件存储系统使用UNIX 的情况下。早在Web 流行之前,FTP 就是在因特网上进行文件传输以及下载软件和源代码的主要手段之一。
流程:
1.客户端连接远程主机上的FTP 服务器。
2.客户端输入用户名和密码(或“anonymous”和电子邮件地址)。
3.客户端进行各种文件传输和信息查询操作。
4.客户端从远程FTP 服务器退出,结束传输。
在底层,FTP 只使用TCP,而不使用UDP。另外,可以将FTP 看作客户端/服务器编程中的特殊情况。因为这里的客户端和服务器都使用两个套接字来通信:一个是控制和命令端口(21 号端口),另一个是数据端口(有时是20 号端口)

用Python 编写FTP 客户端程序:
1.连接到服务器。
2.登录。
3.发出服务请求(希望能得到响应)。
4.退出
from ftplib import FTP
f = FTP(‘some.ftp.server’)
f.login(‘anonymous’, ‘your@email.address’)
:
f. quit()
在一般的FTP 事务中,要使用到的指令有login()、cwd()、dir()、pwd()、stor*()、retr*()和quit()。

FTP 不仅可以用于下载应用程序,还可以用于在不同系统之间传输文件。比如,如果需要传输文件。在跨网络的时候,显然可以使用scp 或rsync 命令,或者把文件放到一个能从外部访问的服务器上。不过,在一个安全网络的内部机器之间移动大量的日志或数据库文件时,这种方法的开销就太大了,因为需要考虑安全性、加密、压缩、解压缩等因素。
如果只是想写一个FTP 程序来在下班后自动移动文件,那么使用Python 是一个非常好的主意。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值