Python - Socket网络编程
在任何类型的通信开始之前,网络应用程序必须创建套接字
套接字地址:主机-端口对
如果套接字像一个电话插孔 - 允许通信的一些基础设施,那么主机名和端口号就像区号和电话号码的组合。然而拥有硬件和通信的能力本身并没有任何好处,除非你知道打电话给谁以及怎么打电话。
除此之外,还必须说明另外一端有人接听,否则就会出现:您所拨打的电话是空号,请核对后再拨
就像平时我们浏览网页看到的服务器没有响应或者404。
有效的端口号为0-65535(小于1024的端口号预留给了系统)
开始实例吧
首先我们要创建套接字必须使用socket.socket()函数,一般语法如下:
socket(socket_family, socket_type, protocol=0)
其中socket_family是AF_UNIX或者AF_INET,socket_type是SOCK_STREAM或SOCK_DGRAM,protocol通常省略,一般为0。
AF_UNIX
是基于文件的套接字,AF_UNIX
在编程的时候并不是太常用。
AF_INET
用于基于网络的Socket
。还有一个地址家族
AF_INET6
, 用于IPv6。
其实还有一些其他地址家族, 哪些要么是专业的, 过时的, 很少使用的, 要么是仍未实现的.
在所有的地址家族中,
AF_INET
是使用最广泛的。
客户端程序如下
from socket import * # 客户端准备连接的服务器的地址 HOST = '192.168.3.128' # 服务器的端口号,保持一致 PORT = 9999 # 服务器的地址 ADDR = (HOST, PORT) # 客户端缓冲区的大小(单位字节) BUFSIZE = 1024 # 所有的套接字都使用 socket 函数来创建 tcpCliSock = socket(AF_INET, SOCK_STREAM) # 客户端去连接服务器 tcpCliSock.connect(ADDR) while True: # 从键盘读取数据 data = input('发送消息:') if not data: break # 给服务器发送消息. 由于 send 只能发送字节数据,所以把字符串编码之后再发送 tcpCliSock.send(data.encode('utf-8')) # 接受服务器发送来的信息 data = tcpCliSock.recv(BUFSIZE) if not data: break # 由于通过网络传递过来的其实是字节数据, 解码之后再输出 print(data.decode('utf-8')) tcpCliSock.close()
服务端代码如下
from socket import * # 服务器要绑定的主机地址,服务器端可为空 HOST = '' PORT = 9999 # 服务器要监听的端口号 ADDR = (HOST, PORT) BUFSIZE = 1024 # 设置服务器的缓冲区大小 while True: tcpSevSock = socket(AF_INET, SOCK_STREAM) # 创建 socket 对象 tcpSevSock.bind(ADDR) # 把 socket 绑定到指定的地址和端口 tcpSevSock.listen(5) # 开启服务器监听器 print('等待客户端连接...') tcpCliSock, cliAddress = tcpSevSock.accept() # 接受客户端的连接 print('客户端连接成功:', cliAddress) while True: try: data = tcpCliSock.recv(BUFSIZE) # 接受客户端发来的数据 except: print("接收出错") break # 如果没有数据 if not data: # 跳出循环 break # 把接收到字节数据解码 data = data.decode('utf-8') print('收到信息:', data) senddata = input('回复信息:') # 编码发送 tcpCliSock.sendall(senddata.encode('utf-8')) # 关闭客户端 tcpCliSock.close() print('有一个客户端下线了...') # 关闭服务器 tcpSevSock.close()
运行时,需要先运行服务端代码,再运行客户端代码!
效果: