python使用socket编程
什么是socket?
Socket接口是TCP/IP网络的API(Application Programming Interface,应用程序编程接口),Socket接口定义了许多函数或例程,程序员可以用它们来开发 TCP/IP网络上的应用程序。
socket不是具体的网络协议,属于存在于tcp、udp协议之上的一个抽象层。是对TCP/IP的封装。
具体使用socket
首先需要导入socket库:import socket
打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可,以下是相关操作:
s.bind():绑定(主机名称、端口到一个套接字上)
s.listen():设置并启动TCP监听
s.accept():等待客户端连接
s.connect():连接指定服务器
s.recv():接受TCP消息
s.send():发送TCP消息
s.recvfrom():接受UDP消息
s.sendto():发送UDP消息
s.close():关闭套接字对象
创建一个socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 建立连接:
s.connect(('www.sina.com.cn', 80))
AF_INET指定使用IPv4协议,如果要用更先进的IPv6,就指定为AF_INET6。SOCK_STREAM指定使用面向流的TCP协议 建立TCP连接后,我们就可以向新浪服务器发送请求
# 发送数据:
s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')
TCP连接创建的是双向通道,双方都可以同时给对方发数据。但是谁先发谁后发,怎么协调,要根据具体的协议来决定。例如,HTTP协议规定客户端必须先发请求给服务器,服务器收到后才发数据给客户端
# 接收数据:
buffer = []while True:
# 每次最多接收1k字节:
d = s.recv(1024)
if d:
buffer.append(d)
else:
break
data = b''.join(buffer)
s.close()
header, html = data.split(b'\r\n\r\n', 1)
print(header.decode('utf-8'))# 把接收的数据写入文件:with open('sina.html', 'wb') as f:
f.write(html)
服务器的编程:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口:
s.bind(('127.0.0.1', 9999))
#调用listen()方法开始监听端口,传入的参数指定等待连接的最大数量:
s.listen(5)print('Waiting for connection...')
while True:
# 接受一个新连接:
sock, addr = s.accept()
# 创建新线程来处理TCP连接:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
#每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接:
def tcplink(sock, addr):
print('Accept new connection from %s:%s...' % addr)
sock.send(b'Welcome!')
while True:
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.' % addr)
连接建立后,服务器首先发一条欢迎消息,然后等待客户端数据,并加上Hello再发送给客户端。如果客户端发送了exit字符串,就直接关闭连接。 要测试这个服务器程序,我们还需要编写一个客户端程序:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 建立连接:
s.connect(('127.0.0.1', 9999))# 接收欢迎消息:
print(s.recv(1024).decode('utf-8'))for data in [b'Michael', b'Tracy', b'Sarah']:
# 发送数据:
s.send(data)
print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
需要打开两个命令行窗口,一个运行服务器程序,另一个运行客户端程序,就可以看到效果了。 (以上内容来自廖雪峰python教程)