收藏链接
服务端要做的事有这些:
Step 1:创建ServerSocket对象,绑定监听的端口
Step 2:调用accept()方法监听客户端的请求
Step 3:连接建立后,通过输入流读取客户端发送的请求信息
Step 4:通过输出流向客户端发送响应信息
Step 5:关闭相关资源
学习链接
Python中socket 类(客户端)的介绍
导入 socket 模块
import socket
创建客户端socket 对象
socket.socket(AddressFamily, Type)
参数说明:
AddressFamily 表示IP地址类型, 分为IPv4和IPv6
Type 表示传输协议类型
方法说明:
connect((host, port)) 表示和服务端套接字建立连接, host是服务器ip地址,port是应用程序的端口号
send(data) 表示发送数据,data是二进制数据
recv(buffersize) 表示接收数据, buffersize是每次接收数据的长度
在Python中创建一个tcp客户端:
import socket
if __name__ == '__main__':
# 1 创建客户端套接字对象tcp_client_1
# 参数介绍:AF_INET 代表IPV4类型, SOCK_STREAM代表tcp传输协议类型 ,注:AF_INET6代表IPV6
tcp_client_1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 2 通过客户端套接字的connect方法与服务器套接字建立连接
# 参数介绍:前面的ip地址代表服务器的ip地址,后面的61234代表服务端的端口号 。
tcp_client_1.connect(("192.168.100.100",61234))
# 将编号好的数据存到变量send_data中,注:encode(encoding='utf-8)是将数据转换成utf-8的格式发送给服务器
send_data = "你好,服务器,我是客户端1号".encode(encoding='utf-8')
# 3 通过客户端套接字的send方法将数据发送给服务器
tcp_client_1.send(send_data)
# 4 通过客户端套接字的recv方法来接受服务器返回的数据存到变量recv_data中,1024是可接收的最大字节数。
recv_data = tcp_client_1.recv(1024)
# 将接收到的服务器数据recv_data通过decode方法解码为utf-8
print(recv_data.decode(encoding = 'utf-8'))
# 5 最后关闭客户端套接字连接
tcp_client_1.close()
Python中socket 类(服务器)的介绍
导入 socket 模块
import socket
创建服务端 socket 对象
socket.socket(AddressFamily, Type)
参数说明:
AddressFamily 表示IP地址类型, 分为IPv4和IPv6
Type 表示传输协议类型
方法说明:
bind((host, port)) 表示绑定端口号, host 是 ip 地址,port 是端口号,ip 地址一般不指定,表示本机的任何一个ip地址都可以。
listen (backlog) 表示设置监听,backlog参数表示最大等待建立连接的个数。
accept() 表示等待接受客户端的连接请求
send(data) 表示发送数据,data 是二进制数据
recv(buffersize) 表示接收数据, buffersize 是每次接收数据的长度
**在Python中创建一个tcp服务器:**
#导入socket模块
import socket
if __name__ == '__main__':
# 创建tcp服务端套接字
# 参数同客户端配置一致,这里不再重复
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
**# 设置端口号复用,让程序退出端口号立即释放,否则的话在30秒-2分钟之内这个端口是不会被释放的,这是TCP的为了保证传输可靠性的机制。
tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)**
# 给客户端绑定端口号,客户端需要知道服务器的端口号才能进行建立连接。IP地址不用设置,默认就为本机的IP地址。
tcp_server.bind(("", 61234))
##s.bind(("0.0.0.0",1234)) #网卡 ip地址0.0.0.0b表示主机任意网卡都可以与此连接
# 设置监听
# 128:最大等待建立连接的个数, 提示: 目前是单任务的服务端,同一时刻只能服务与一个客户端,后续使用多任务能够让服务端同时服务与多个客户端
# 不需要让客户端进行等待建立连接
# listen后的这个套接字只负责接收客户端连接请求,不能收发消息,收发消息使用返回的这个新套接字tcp_client来完成
tcp_server.listen(128)
# 等待客户端建立连接的请求, 只有客户端和服务端建立连接成功代码才会解阻塞,代码才能继续往下执行
# 1. 专门和客户端通信的套接字: tcp_client
# 2. 客户端的ip地址和端口号: tcp_client_address
tcp_client, tcp_client_address= tcp_server.accept()
# 代码执行到此说明连接建立成功
print("客户端的ip地址和端口号:", tcp_client_address)
# 接收客户端发送的数据, 这次接收数据的最大字节数是1024
recv_data = tcp_client.recv(1024)
# 对服务器发来的数据进行解码保存到变量recv_content中
recv_content = recv_data.decode(encoding = "utf-8")
print("接收客户端的数据为:", recv_content)
# 准备要发送给服务器的数据
send_data = "好的,消息已收到".encode(encoding = "utf-8")
# 发送数据给客户端
tcp_client.send(send_data)
# 关闭服务与客户端的套接字, 终止和客户端通信的服务
tcp_client.close()
# 关闭服务端的套接字, 终止和客户端提供建立连接请求的服务 但是正常来说服务器的套接字是不需要关闭的,因为服务器需要一直运行。
# tcp_server.close()
# 导入套接字模块
import socket
# 导入线程模块
import threading
# 定义个函数,使其专门重复处理客户的请求数据(也就是重复接受一个用户的消息并且重复回答,直到用户选择下线)
def dispose_client_request(tcp_client_1,tcp_client_address):
# 5 循环接收和发送数据
while True:
recv_data = tcp_client_1.recv(4096)
# 6 有消息就回复数据,消息长度为0就是说明客户端下线了
if recv_data:
print("客户端是:", tcp_client_address)
print("客户端发来的消息是:", recv_data.decode())
send_data = "消息已收到,正在处理中...".encode()
tcp_client_1.send(send_data)
else:
print("%s 客户端下线了..." % tcp_client_address[1])
tcp_client_1.close()
break
if __name__ == '__main__':
# 1 创建服务端套接字对象
tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置端口复用,使程序退出后端口马上释放
tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
# 2 绑定端口
tcp_server.bind(("",61234))
# 3 设置监听
tcp_server.listen(128)
# 4 循环等待客户端连接请求(也就是最多可以同时有128个用户连接到服务器进行通信)
while True:
tcp_client_1 , tcp_client_address = tcp_server.accept()
# 创建多线程对象
thd = threading.Thread(target = dispose_client_request, args = (tcp_client_1,tcp_client_address))
# 设置守护主线程 即如果主线程结束了 那子线程中也都销毁了 防止主线程无法退出
# thd.setDaemon(True)
# 启动子线程对象
thd.start()
# 7 关闭服务器套接字 (其实可以不用关闭,因为服务器一直都需要运行)
# tcp_server.close()
总结:可以看到TCP服务器同时连接了两个用户,并且与每个用户进行了多次通信,直到客户端下线。
学习记录1server
import socket
new_socket =socket.socket()
ip="127.0.0.1"
port=8080
new_socket.bind((ip,port))
new_socket.listen(5)
while True:
new_cil,addr =new_socket.accept() #建立链接 addr 返回端口号和地址 阻塞到有客户端接入
new_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)##断开后 端口立马释放 不占用端口
print("新进来的地址是",addr)
print(new_cil.recv(8080).decode())#接受客户端来的数据 recv参数最大的接受字长 请求数据 read
new_cil.send("答案是6".encode(encoding='utf-8'))#发送数据给客户端 回应数据 write
new_cil.close() #关闭链接
首先,客户端和服务端会分别新建一个socket,服务端的socket需要通过bind()来绑定上端口,启动listen()进行实时监听,并等待客户端的接入,即accept()。而客户端则需要通过服务器IP和端口两个参数来建立connect()连接,此时,服务器会得到有新客户端连接的信息,启动read()等待客户端数据的传人,客户端如果成功接收到服务端的连接成功后,继续执行write()来向服务端发生数据,同理,服务端也使用这样的模式回馈客户端的数据,知道客户端关闭,服务端会收到客户端退出连接的消息,服务器重新进入等待状态,等待新客户端的进入。
client
import socket
ip ="127.0.0.1"
port =8080
new_socket =socket.socket()#创建socket对象
new_socket.connect((ip,port)) #链接
new_socket.send("服务器,帮我算一下5+1等于多少".encode(encoding='utf-8')) #发送数据 回应数据 write 对应server的read
back_str = new_socket.recv(port).decode()#结束数据 请求数据 read 对应server的write
new_socket.close()