socket(中文名称:套接字)是应用层与传输层(TCP/UDP协议)的接口。是对TCP/IP的封装。是操作系统的通信机制。应用程序通过socket进行网络数据的传输。Python中的socket是我们常用的模块,当然还有socketserver模块(对socket模块的进一步封装)
二:SOCKET相关概念
1、端口
在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应用程序),因此,在网络协议中使用端口号识别主机上不同的进程。
例如:http使用80端口,FTP使用21端口。
2、协议
2.1 TCP:
TCP是一种面向连接的、可靠的,基于字节流的传输层通信协议。为两台主机提供高可靠性的数据通信服务。它可以将源主机的数据无差错地传输到目标主机。当有数据要发送时,对应用进程送来的数据进行分片,以适合于在网络层中传输;当接收到网络层传来的分组时,它要对收到的分组进行确认,还要对丢失的分组设置超时重发等。为此TCP需要增加额外的许多开销,以便在数据传输过程中进行一些必要的控制,确保数据的可靠传输。因此,TCP传输的效率比较低。
使用TCP传输的用例:
服务端的代码:socket_server.py
#导入模块
import socket
#实例初始化
client = socket.socket()
#访问服务器端口
ip_port = ("127.0.0.1",8888)
#连接主机
client.connect(ip_port)
while True:
#输入发送的消息
data = client.recv(1024)
#打印接收的数据
# 此处的byte型数据特指python3.x以de())
print(data.decode())
#定义一个循环,不断发送消息
#输入发送的消息
msg_input = input("请输入发送的消息:")
#消息发送
client.send(msg_input.encode())
if msg_input == "exit":
break
data = client.recv(1024)
print(data.decode())
客户端的代码:socket_client.py
#导入模块
import socket
#实例初始化
client = socket.socket()
#访问服务器端口
ip_port = ("127.0.0.1",8888)
#连接主机
client.connect(ip_port)
while True:
#输入发送的消息
data = client.recv(1024)
#打印接收的数据
# 此处的byte型数据特指python3.x以de())
print(data.decode())
#定义一个循环,不断发送消息
#输入发送的消息
msg_input = input("请输入发送的消息:")
#消息发送
client.send(msg_input.encode())
if msg_input == "exit":
break
data = client.recv(1024)
print(data.decode())
结果展示:
先运行服务端程序,等待端口进行监听之后,在运行客户端程序,客户端运行程序后输入123的输入值,返回服务端给我们的随机数值。
UDP
UDP是一种简单的、面向数据报的无连接的协议,提供的是不一定可靠的传输服务。所谓“无连接”是指在正式通信前不必与对方先建立连接,不管对方状态如何都直接发送过去。这与发手机短信非常相似,只要知道对方的手机号就可以了,不要考虑对方手机处于什么状态。UDP虽然不能保证数据传输的可靠性,但数据传输的效率较高。
使用UDP传输的实例:
服务端:
#导入模块
import socket
#创建实例
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#定义ip地址
ip_port = ("127.0.0.1",8888)
#绑定监听
sk.bind(ip_port)
#不断循环接收数据
while True:
#接收数据
data = sk.recv(1024)
#定义数据类型
print(data.decode())
客户端:
#导入模块
import socket
#定义实例
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#定义链接的服务器
ip_port = ("127.0.0.1", 8888)
#循环数据的输入
while True:
#输入发送的信息
msg_input = input("请输入发送的消息:")
if msg_input == "exit":
break
sk.sendto(msg_input.encode(),ip_port)
sk.close()
结果展示:
UDP实现数据的传送,并且是不间断地传送数据。结果一直在被接收中。
下面编写使用Socket模块,编写一个文件传送与接收的脚本实例:
服务端(文件接收端):
#导入模块
import socket
#模块进行实例化
sk = socket.socket()
#设置端口通讯地址
ip_port = ('127.0.0.1',9999)
#地址绑定
sk.bind(ip_port)
#最大连接数量
sk.listen(5)
#进入循环接收数据
while True:
#等待客户端连接
conn,address = sk.accept()
#一直使用当前连接进行数据发送
#直到标志接收完成
#循环接收数据
while True:
#打开文件
with open("file","ab") as f:
#准备写入数据
data = conn.recv(1024)
#进行判断数据是否接收完毕
if data == b'quit':
break
#写入文件数据
f.write(data)
# 接收完成标志
conn.send('success'.encode())
#打印文件信息
print('文件接收完成')
sk.close()
客户端(文件发送端):
#导入模块
import socket
#进行实例化
sk = socket.socket()
#设置通讯端口
ip_port = ('127.0.0.1',9999)
#IP地址绑定
sk.connect(ip_port)
#打开传送的文件
with open('socket_client_udp.py','rb') as f:
#分割每一段
for i in f :
#数据的上传
sk.send(i)
#等待接收的完成
data = sk.recv(1024)
#判断数据是否接收完毕
if data != b'success':
break
#给服务器发送结束的信号
sk.send('quit'.encode())
结果呈现:
先运行服务端进行端口的监听。在运行客户端进行文件的发送,当发送完毕后,服务端完成工作进行打印出来。
服务反馈代码接收已经完成了。
总结:Socket作为接收数据的模块,可以高效接收各个数据包。可以根据自己业务的需求,选择合适的传输模式进行传输。我计划下期版本在加强一下,把他封装成函数,就可以直接调用。实现TFTP的传输效果,出现页面让用户选择传输的文件进行上传了。
借鉴参考地址:慕课网、数不清的CSDN的网友们链接。