注意ip_address的设置,一开始会认为这个地址是我监听的地址,实际上这个地址应该是我去限定一个地址,只有这个ip子网下的地址传过来的数据我才可以接收的到,对于端口号也可以这样理解,也就是我只能监听到这个端口。为此我们要是对安全没有很高的要求,我们可以将地址设置成为0.0.0.0,这样就可以实现多台终端之间进行通信。
服务器端代码:
import socket # 导入 socket 模块
from threading import Thread
# ADDRESS = ('0.0.0.0', 8080) # 绑定地址
g_socket_server = None # 负责监听的socket
g_conn_pool = [] # 连接池
ip_address = '0.0.0.0'
port = 8080def init():"""初始化服务端"""global g_socket_serverg_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建 socket 对象g_socket_server.bind((ip_address, port))g_socket_server.listen(5) # 最大等待数(有很多人理解为最大连接数,其实是错误的)print("服务端已启动,等待客户端连接...")def accept_client():"""接收新连接"""while True:client, _ = g_socket_server.accept() # 阻塞,等待客户端连接# 加入连接池g_conn_pool.append(client)# 给每个客户端创建一个独立的线程进行管理thread = Thread(target=message_handle, args=(client,))# 设置成守护线程thread.setDaemon(True)thread.start()def message_handle(client):"""消息处理"""while True:bytes = client.recv(1024)print("客户端消息:", bytes)client.send(b'okk')if len(bytes) == 0:client.close()# 删除连接g_conn_pool.remove(client)print("有一个客户端下线了。")breakif __name__ == '__main__':init()# 新开一个线程,用于接收新连接thread = Thread(target=accept_client)thread.setDaemon(True)thread.start()# 主线程逻辑while True:cmd = input("""--------------------------
输入1:查看当前在线人数
输入2:关闭服务端
""")if cmd == '1':print("--------------------------")print("当前在线人数:", len(g_conn_pool), g_conn_pool)elif cmd == '2':exit()
客户端代码就随便写了,以下是一个示例:
import socket
client = socket.socket()
#
# client.connect(('192.168.43.113', 8080))
client.connect(('3n2963t136.zicp.vip', 38381))
print('-------------------------')
cmd = '01 01 01 0A 01 02 01 01 01'
client.send(cmd.encode("utf-8")) #send只能发送bytes格式数据
input()
client.close()
在这里要注意的是我的client.connect(('3n2963t136.zicp.vip', 38381)),这句代码跟终端设置的不一样,因为我用了一些工具将内网转成外网,这样使得在任何地方都可以进行连接,如果你没有这方面的需求,端口号设置成与服务器端一致,IP地址填写服务器端的IP地址,便可实现通信。