#服务器端
import socket import multiprocessing # 创建套接字 skt = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)#括号里不写参数默认是这个skt = socket.socket()等价 # family:协议族,socket.AF_INET表示IPv4 # type:传输协议,socket.SOCK_STREAM表示TCP协议 # 设置地址可重用 skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 这里value设置为1,表示将SO_REUSEADDR标记为TRUE, # 操作系统会在服务器socket被关闭或服务器进程终止后马上释放该服务器的端口,否则操作系统会保留几分钟该端口。 # 绑定主机和端口 skt.bind(('10.8.165.6', 8888)) #改成你自己的ip地址 # 监听服务 skt.listen(100) # listen里有个参数backlog是指定tcpsever可以同时接受多少个客服端的连接申请,当超过此数时server将拒绝客户端的连接申请, # 给出socket.error: [Errno 10061]错误。tcp的server尽管可以同时接受n个客服端连接,但只能和第一个连接的客服端互相通信, # 当第一个tcp连接的客户端关闭后才能和第二个连接申请的客户端通信,即后边的被阻塞了,一次只能和一个tcp客户端进行通信。 def echo(client_skt, client_addr): while True: # 接收客户端数据 recv_data = client_skt.recv(1024)#recv()接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 #接受小于1024字节的数据 host = socket.getfqdn(client_addr[0])#由计算机ip地址获取计算机主机名字 #client_addr返回两个参数,第一个是ip地址,第二个是线程暂用的临时端口号 print(host, ':', recv_data.decode('utf-8'), sep='') #关键字参数sep是实现分隔符,比如多个参数输出时想要输出中间的分隔字符 # print(1, 2, 3, sep=',', end='\r\n') 1,2,3 输出时一直输出到sep 逗号前的逗号 # print(1, 2, 3, sep=' ', end='\r\n')1 2 3 # 向客户端发送数据,实现镜像发送 client_skt.send(recv_data) if recv_data == b'byebye': #b是字节流,因为客户端传来的数据是编码成utf-8格式的 break client_skt.close() if __name__ == '__main__': while True: # 等待客户端连接,会阻塞在这里 client_skt, client_addr = skt.accept() print(client_skt,client_addr) p = multiprocessing.Process(target=echo, args=(client_skt, client_addr)) p.start() client_skt.close() skt.close()
#客户端
import socket # 创建套接字 skt = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) # family:协议族,socket.AF_INET表示IPv4 # type:传输协议,socket.SOCK_STREAM表示TCP协议 # 连接服务器 skt.connect(('10.8.165.6', 8888)) while True: data = input('>>>:') # 向服务器发送数据 skt.send(data.encode('utf-8')) # 等待接收服务器返回的数据 recv_data = skt.recv(1024) print('服务器:', recv_data.decode('utf-8')) if recv_data == b'byebye': break skt.close()