在Python中使用socket模块的socket函数可以完成,语法格式如下:
s=socket.socket(AddressFamily, Type)
函数socket.socket创建一个socket,返回该socket的描述符。该函数带有两个参数。
-
Address Family:可以选择AF_INET(用于Internet进程间通信),或者AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET。
-
Type:套接字类型,可以是SOCK_STREAM(流式套接字,主要用于TCP协议)或者SOCK_DGRAM(数据报套接字,主要用于UDP协议)。
socket对象的内置方法
方法 | 描述 |
---|---|
s.bind() | 绑定地址(host,port)到套接字,在AF_INET下以元组(host,port)的形式表示地址。 |
s.listen() | 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5即可 |
s.accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来。 |
s.connect() | 主动初始化TCP服务器连接,一般address的格式为元组(hostname,port),如果连接出错,返回socket,error错误 |
s.recv() | 接收TCP数据,以字符串形式返回。bufsize指定要接收的最大数据量;flag提供有关消息的其他信息,通常可以忽略 |
s.send() | 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小 |
s.sendall() | 完整发送TCP数据,将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功则返回Node,失败则抛出异常 |
s.recvfrom() | 接收UDP数据。与recv()类似,但返回值是(data,address)元组。其中data是包含接收数据的字符串,address是发送数据的套接字地址 |
s.sendto() | 发送UDP数据,将数据发送到套接字。address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数 |
s.close() | 关闭套接字 |
创建TCP服务器
完成一个TCP服务器的功能,需要流程如下:
- 使用socket创建一个套接字。
- 使用bind绑定IP和端口。
- 使用listen使套接字变为可以被动连接。
- 使用accept等待客户端的连接。
- 使用recv/send接收发送数据。
创建一个server.py文件,代码如下:
import socket #导入socket模块
host='127.0.0.1' #主机IP
port=8080 #端口号
web=socket.socket() #创建socket对象
web.bind((host,port)) #绑定端口
web.listen(5) #设置最多连接数
print('服务器等待客户端连接...')
#开户死循环
while True:
conn,addr=web.accept() #建立客户端连接
data=conn.recv(1024) #获取客户端请求数据
print(data) #打印接收到的数据
conn.sendall(b'HTTP/1.1 200 OK\r\n\r\nHello World') #向客户端发送数据
conn.close() #关闭连接
创建一个client.py文件,代码如下:
import socket
s=socket.socket()
host='127.0.0.1'
port=8080
s.connect((host,port))
send_data=input("请输入要发送的数据:")
s.send(send_data.encode())
#接收对方发送过来的数据,最大接收1024个字节
recvData=s.recv(1024).decode()
print('接收到的数据为:',recvData)
#关闭套接字
s.close()
制作简易聊天窗口:
创建server.py文件,作为服务器程序,代码如下:
import socket
host=socket.gethostname()
port=12345
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
sock,addr=s.accept()
print('连接已经建立')
info=sock.recv(1024).decode()
while info!='byebye':
if info:
print('接收到的内容:'+info)
send_data=input('输入发送内容:')
sock.send(send_data.encode())
if send_data=='byebye':
break
info=sock.recv(1024).decode()
sock.close()
s.close()
创建client.py文件,作为客户端程度,代码如下:
import socket
s=socket.socket()
host=socket.gethostname()
port=12345
s.connect((host,port))
print('已连接')
info=''
while info!='byebye':
send_data=input('输入发送内容:')
s.send(send_data.encode())
if send_data=='byebye':
break
info=s.recv(1024).decode()
print('接收到的内容:'+info)
s.close()
UDP
不同于TCP协议,UDP协议是面向无连接的协议。
使用UDP协议时,不需要建立链接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,数据无法保证一定到达。
虽然用UDP传输数据不可靠,但它的优点是比TCP协议速度快。
对于不要求可靠到达的数据,就可以使用UDP协议。
UDP是面向消息的协议,通信时不需要建立连接,数据的传输自然是不可靠的。
UPD一般用于多点通信和实时的数据业务。
- 语音广播
- 视频
- 聊天软件
- TFTP(简单文件传送)
- SNMP(简单网络管理协议)
- RIP(路由信息协议,如报告股票市场、航空信息)
- DNS(域名解释)
创建UDP服务器
创建udp_server.py文件,代码如下:
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('127.0.0.1',8888))
print('绑定UDP到8888端口')
data,addr=s.recvfrom(1024)
data=float(data)*1.8+32
send_data='转换后的温度(单位:华氏温度):'+str(data)
print('Received from %s:%s.'%addr)
s.sendto(send_data.encode(),addr)
s.close()
创建UDP客户端
创建一个UDP客户端的流程步骤如下:
- 创建客户端套接字
- 发送/接收数据。
- 关闭套接字
创建udp_client.py文件,代码如下:
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
data=input('请输入要转换的温度(单位:摄氏温度):')
s.sendto(data.encode(),('127.0.0.1',8888))
print(s.recv(1024).decode())
s.close()