socket库调用
import socket
服务端socket生成
import sys
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 防止socket server重启后端口被占用(socket.error: [Errno 98] Address already in use)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 6666))
s.listen(10)
except socket.error as msg:
print(msg)
sys.exit(1)
print('Waiting connection...')
代码解释:
socket.socket() 生成socket实例,参数为socket形式
s.setsockopt(socket层,想要设置的选项,设置的值) socket对象定义的方法,用于设定该套接字的相关参数
s.bind( ( ip(string),port(int) ) ) 将socket对象绑定到一个地址,注意该地址用元组进行标识是本地服务器地址,相当于为服务端创建socket
s.listen(最大连接数量) 设置该socket的最大连接数量,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数,这个值不能无限大,因为要在内核中维护连接队列
进入循环进行连接
import threading
while 1:
conn, addr = s.accept()
t = threading.Thread(target=deal_data, args=(conn, addr))
t.start()
while 1: 进入循环,即每当accept一个连接,就循环一次
s.accept() 阻塞式的连接,在未建立连接前,进程会在这一步阻塞
返回值conn代表新的套接字,对应客户端和服务端间的连接
addr为字符串,表示客户端的地址,用于向服务端传递连接信息
threading.Thread(target(线程的函数名),args(向线程内函数传递参数,元组形式)) 每当建立一个连接,就开一个线程
处理服务端接受的数据
import sys
def deal_data(conn, addr):
print('Accept new connection from {0}'.format(addr))
conn.send(('Hi, Welcome to the server!').encode())#send内容形式一
while 1:
data = conn.recv(1024)
print('{0} client send data is {1}'.format(addr, data.decode()))
time.sleep(1)
if data == 'exit' or not data:
print('{0} connection close'.format(addr))
conn.send(bytes('Connection closed!'),'UTF-8')#send内容形式二
break
conn.send(bytes('Hello, {0}'.format(data),"UTF-8"))
conn.close()
conn.send(信息) 通过在客户端和服务端间的套接字进行传输,注意信息需要经过编码成二进制
while 1: 进入循环,每从客户端接收到一个信息,就循环一次
conn.recv(信息最大大小) 对应bytes,同样是阻塞式的,未接受到之前不会继续
返回值data代表接受的信息,是编码后的,需要解码
当data=‘exit’时,服务端推出while的死循环,相当于互动结束
conn.close() 关闭客户端和服务端间套接字
⚠注意到服务端一共有两个套接字,s和c
s是服务端本地的套接字,用于和本机地址绑定并监听请求,利用accept()创建服务端和客户端间一对一的套接字。
c就是用于连接的套接字,主要承担通信,并具有明显的生命周期。
客户端
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 6666))
except socket.error as msg:
print(msg)
sys.exit(1)
print(s.recv(1024)) # 目的在于接受:Accept new connection from (...
while 1:
data = input('please input work: ').encode()
s.send(data)
print('aa', s.recv(1024))
if data == 'exit':
break
s.close()
socket.socket() 创建套接字对象
s.connect(用元组表示的地址) 利用connect方法绑定的套接字,说明是用于连接的,故有明显生命周期