连接建立后,服务器首先发一条欢迎消息,然后等待客户端数据,并加上Hello再发送给客户端。如果客户端发送了exit字符串,就直接关闭连接。
参考链接,不完全一样。
写的时候服务端和客户端都在实机win10,powershell里ctrl+c无法结束服务端,ctrl+pause可以结束。但是有个问题,客户端关闭了连接,服务端也关闭了对应的连接,这时服务端用于和这个客户端通信的线程会自动释放资源或停止吗?不会的话应该怎么设置才能让它自动释放资源或停止?希望有人能解答。
接着测试多线程,虚拟机网络适配器设为桥接模式,使虚拟机和实机处于同一网段。虚拟机kali作服务端,虚拟机win7作客户端,实机win10作客户端,服务端可同时响应这2个客户端。
服务端
import socket
import threading
import time
HOST='192.168.123.23'
PORT=1234
def tcp_link(client_socket,client_addr):
print(f'{client_addr}上线了')
client_socket.send(b'Welcome!')
while True:
data=client_socket.recv(1024)
time.sleep(1) # 不睡眠的话客户端收到下面代码发的数据的速度太快
if not data or data.decode('utf-8')=='exit':
break
# client_socket.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8')) # 或者下面2行的写法
# data=data.decode('utf-8');client_socket.send(f'Hello {data}'.encode('utf-8')) # 直接写下面1行的写法,没写出来,想到分步写,先解码再编码,写了末尾注释的测试代码,测好后合并成下面1行的写法
client_socket.send(f'Hello {data.decode("utf-8")}'.encode('utf-8'))
client_socket.close()
print(f'{client_addr}下线了')
if __name__=='__main__':
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 创建套接字
server_socket.bind((HOST,PORT)) # 绑定服务端地址和端口,参数是一个元组
server_socket.listen() # 监听端口,参数可以设置最大连接数,超过后排队
print('等待连接中')
while True: # 永久接受客户端的连接
client_socket,client_addr=server_socket.accept() # 阻塞式等待客户端连接,返回用于和该客户端通信的新套接字,及客户端地址(里面的端口是转换后的)。无客户端连接时会阻塞,一直等待连接
t=threading.Thread(target=tcp_link,args=(client_socket,client_addr)) # 每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接
t.start() # 客户端程序运行完毕就退出了,而服务器程序会永远运行下去,需要手动结束
'''
str=b'world'
new_str=str.decode('utf-8')
print(type(str))
print(type(new_str))
print(type(f'hello {new_str}')) # f''整体是字符串,要求socket发送的数据是bytes对象,那就对整体编码,就是下1行
print(type(f'hello {new_str}'.encode('utf-8'))) # encode()返回编码后的字符串,是一个bytes对象
'''
客户端
import socket
HOST='192.168.123.23'
PORT=1234
if __name__=='__main__':
client_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 创建套接字
client_socket.connect((HOST,PORT)) # 连接服务端地址和端口,参数是一个元组
print(client_socket.recv(1024).decode('utf-8')) # 接收服务端发来的Welcome
for i in [b'Michael',b'Tracy',b'Sarah']:
client_socket.send(i)
print(client_socket.recv(1024).decode('utf-8'))
client_socket.send(b'exit')
client_socket.close()