因为课题原因,需要使用socket通信,以下为自学笔记。
Socket介绍
Socket源自于Unix系统,一切皆文件,socket其实也就是一种特殊的文件,所以socket函数就是对其进行的打开关闭、读写等操作。
参考张岩林大佬的描述,socket模块就是针对服务器端(Server)和客户端(Client)进行的【打开】【读写】【关闭】操作,具体流程图如下所示:
实战操作
了解了Socket通信的基本原理以及流程后,开始动手自己编写客户端和服务器端的socket通信。
客户端
首先明白什么事客户端,在发起TCP连接的时候,通常主动发起连接的便是客户端(Client),被动响应连接的称作服务器端(Server)。比如浏览网页的时候,本机就是客户端,访问的网页便是服务器端。
下面是一个简单的基于TCP通信的Socket连接。以客户端为例:
#导入socket库
import socket
# 创建一个socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('www.baidu.com.cn', 80))
cmd = raw_input("Please Input Some Commands")
s.sendall(cmd)
#定义一个buffer来接收数据
buffer = []
#利用while循环实现接收所有数据的功能
while True:
d = s.recv(1024)
if d:
#append操作,不断将d中的数据添加给buffer
buffer.append(d)
else:
break
#将buffer中的元素联接成一个新的字符串
data = b''.join(buffer)
print(data)
#关闭连接
s.close()
首先,导入socket库,创建一个socket通信,其中socket.AF_INET指的是使用IPv4协议,socket.AF_INET6代表IPv6协议(IPV4和IPV6协议的区别自行谷歌)
然后SOCK_STREAM代表使用流式socket,for TCP,SOCK_DGRAM指的是数据包式socket,for UDP
到这里,一个正常的socket对象已经创建成功,接下来要建立连接。连接需要服务器的两个参数:IP地址和端口号,此处使用了域名直接转IP地址,而80端口是Web服务的标准端口,通常都会预留一些端口给专用的服务,例如SMTP服务是25端口,FTP服务是21端口,工业协议Modbus/TCP是502端口等等。将两个参数作为一个元组(tuple)进行输入。
接下来可以接收服务器返回的数据,可以调用recv(max)函数来指定一次最多接收的字节数量,可以用一个while循环来实现接收返回数据的功能。
最后使用s.close()来关闭连接即可。
服务器端
通过第一张socket通信流程图可以看到,服务器端实现要比客户端更加复杂。
首先服务器端要绑定一个端口并且进行监听,如果监听到客户端发送过来的请求,那么服务器端就与客户端建立socket连接。
那么服务器如何区分到底应该和哪个客户端进行绑定连接的呢。一个Socket由以下四个参数来唯一确定:
- 服务器地址
- 服务器端口号
- 客户端地址
- 客户端端口号
首先,仿照客户端通信,先创建一个socket通信
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
然后绑定需要监听的地址和端口号, 但是一台计算机中可能存在多块网卡,可以通过IP地址来区分绑定到哪一张网卡,例如0.0.0.0表示绑定到所有网络地址,127.0.0.1表示绑定到本机地址,此时,客户端必须同时在本机运行才能够正常连接,外部的计算机是无法进行连接的。
接下来指定绑定的端口号,端口号小于1024指的是Internet标准服务的端口,需要管理员权限,大于1024的端口则可以任意使用。
# 绑定IP地址和端口号:
s.bind(('127.0.0.1', 8888))
按照流程图,接下来需要进行监听操作,调用listen()方法可以实现
#监听端口
#listen()传入的参数为等待连接的最大数量
s.listen(5)
print('Waiting for connection...')
接来下,依然利用一个while循环来实现接收客户端的连接操作。
while True:
# 接受一个新连接,并返回新的套接字和IP地址
conn, addr = s.accept()
print("Connected to",addr)
conn.send("Hello World")
conn.close()
总结
今天先写到这吧,过两天写一下整体的实现,和如何创建新线程的方法进行连接。新手写博,只是做个笔记。