1、socket
套接字(Socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。最早是应用于unix系统的一种通信模式,unix系统下的所有操作均是面向文件,Socket的通信模式也是基于文件操作,客户端和服务端均对一个文件完成“打开-读/写-关闭”操作,通过此文件传输信息完成通信。
Socket(套接字)可以看成是两个网络应用程序进行通信时,各自通信连接中的端点。它是网络环境中进程间通信进程间通信的API(应用程序编程接口),也是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连进程。通信时其中一个网络应用程序将要传输的一段信息写入它所在主机的 Socket中,该 Socket通过网络接口卡网络接口卡(NIC)与相连的传输介质将这段信息送到另外一台主机的 Socket中,使对方能够接收到这段信息。
Socket是IP地址和端口组合,提供向应用层进程传送数据包的机制。
Socket是面向客户/服务器模型而设计的。通信的一方扮演客户机的角色,另一方扮演服务器的角色。服务器在运行中一直监听套接字指定的传输层端口,并等待着客户机的连接请求。当服务器端收到客户机发来的连接请求以后,服务器会接受客户机的连接请求,双方建立连接后,就可进行数据的传递。
2、服务类型
根据套接字的不同类型,TCP/IP协议将套接字调用分为面向连接服务和无连接服务。
面向连接服务(TCP)的主要特点如下:
(1)数据传输过程必须经过建立连接、维护连接和释放连接3个阶段 ;
(2)在传输过程中,各分组不需要携带目的主机的地址 ;
(3)可靠性好,但由于协议复杂,通信效率不高 。
面向无连接服务(UDP)的主要特点如下:
(1)不需要连接的各个阶段 ;
(2)每个分组都携带完整的目的主机地址,在系统中独立传送 ;
(3)由于没有顺序控制,所以接收方的分组可能出现乱序、重复和丢失现象;
(4)通信效率高,但可靠性不能确保。
3、代码实现
3.1 TCP
1)客户端
import socket
Tcp_Client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#其中 socket.AF_INET 指名TCP/IP协议 ,socket.SOCK_STREAM表明面向连接的TCP
#连接服务器
Server_IP = ("x.x.x.x",8888) #x.x.x.x服务器的IP地址,8888为服务器监听的端口号
Tcp_Client.connect(Server_IP) #连接指定的服务器及端口号
#连接成功、接收服务端信息
data_Server = Tcp_Client.recv(1024) #接收服务端的字节数为1024
print(data_Server.decode()) #将接收的二进制数据转换为字符串
2)服务器端
import socket
# 创建TCP服务器端
Tcp_Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Tcp_Server.bind(("0.0.0.0",8888)) #将服务器IP(服务器本机IP,如为0.0.0.0表示服务器的所有接口)和端口与套接字绑定,8888为服务器监听端口号
Tcp_Server.listen(5) #设置该进程socket最多处理5个客户端连接请求
#等待客户端连接
Tcp_Client,info = Tcp_Server.accept() #阻塞程序运行,直到收到客户端连接
#向客户端发送消息
Tcp_Client.send("成功连接服务器!".encode()) #将发送的数据进行UTF-8编码
3)通信
服务器端:
调用Tcp_Client.send(),发送消息;Tcp_Client.recv(1024),接收消息。
客户端:
调用Tcp_Client.recv(1024)接收消息;Tcp_Client.send(),发送消息。
通信结束:
关闭Tcp_Client .close();Tcp_Server.close()
3.2 UDP
1)发送数据
# 创建套接字
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定
s.bind(("", 7892))
# 获取发送的数据
send_content = input("输入发送的内容:")
# 获取对方 ip
send_ip = input("目标 ip:")
# 获取对方端口
send_port = int(input("目标端口:"))
# 发送数据
s.sendto(send_content.encode("utf-8"), (send_ip, send_port))
2)接收数据
# 创建套接字
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", 7892))
recv_content, client_info = s.recvfrom(1024)
print(">>>%s(%s):%s" % (client_info[0], client_info[1], recv_content.decode("utf-8")))