socket实现多个连接
前戏很重要~~
在实现多个连接之前,先实现下多次发送和接收数据。
如果要多次接收数据,那么在服务器端的接收和客户端的发送部分就必须使用循环。
以下代码在python3.5下运行。
服务器端:
socket实现多个连接 前戏很重要~~ 在实现多个连接之前,先实现下多次发送和接收数据。 如果要多次接收数据,那么在服务器端的接收和客户端的发送部分就必须使用循环。 以下代码在python3.5下运行。 服务器端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#服务器端 import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen() #监听 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print (data) conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端:
1 2 3 4 5 6 7 8 9 10 11 12 |
#客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print (data.decode()) # client.close() |
直接把用户输入的内容发送给服务器。 执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#=========客户端======== >>你好 你好 >>中国 中国 >>hello world HELLO WORLD >> Process finished with exit code 1 #========服务器端========= b '\xe4\xbd\xa0\xe5\xa5\xbd' b '\xe4\xb8\xad\xe5\x9b\xbd' b 'hello world' Traceback (most recent call last): ... ConnectionResetError: [WinError 10054 ] 远程主机强迫关闭了一个现有的连接。 Process finished with exit code 1 |
可以看到这里已经实现了多少发送和接收的效果,但是如果客户端断开连接,服务器端也被迫中断。 在python2下如果客户端突然中断,服务器端并不会直接中断。 以下实验在Python2环境下。 单个客户端通信 服务器端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 最多可以挂起多少个连接 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#-*- coding=utf-8 -*- #客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = raw_input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print ( 'recv:' ,data.decode()) # client.close() |
开始通信: 首先客户端先发送数据: 在看服务器端接收: 发送接收正常。 现在用CTRL+c断开客户端之后服务器端的情况。 修改服务器端代码, 加一个统计,查看下什么时候开始死循环的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 count = 0 #统计 条件 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 count + = 1 if count > 10 : break server.close() |
客户端发送接收数据结果。 服务器端发送接收数据结果。 因为客户端断开,服务器端接收的都是空。 优化服务器端,断开就退出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) #客户端断开就退出 break conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端: 服务器端: 客户端断开,服务器直接退出。 多个客户端通信 怎么让服务器端一直保持接收状态呢? 想要 一直保持接收状态就要在客户端断开之后,继续执行server.accept()。 对的。在server.accept()之前在加一个while,当一个客户端断开了之后break,跳出最里层的循环的时候,又继续server.accept()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 while True : conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) break conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
修改并启动服务器端代码。 客户端1 客户端2 服务器端 断开客户端1之后: 服务器端 客户端2 简单的实现了能多个连接,但是只能同时跟一个客户端通信的功能。。 模拟SSH 既然可以发数据过来,那么也可以把这个数据做为命令执行。 首先修改服务器端,发送过来的命令执行并把结果返回给客户端。 服务器端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#-*-coding:utf-8 -*- import socket import os server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 while True : conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) break res = os.popen(data).read() conn.send(res) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#-*- coding=utf-8 -*- #客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = raw_input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print (data) # client.close() |
执行客户端 服务器端 这里是有返回的,如果一条命令的返回数据大于了定义的接收的大小,那么这次客户端接收的数据就不全,剩余的数据要等到服务器下次发送才能接收过来。比如定义的接收数据大小是1024,那么一次只能接收1024字节的数据。其余的数据都是在缓冲区里面。因为客户端不知道要接收几次。所以服务器端应该把本次要发送的数据大小先发过来,客户端就知道要接收几次了。 |
|
客户端:
1 2 3 4 5 6 7 8 9 10 11 12 |
#客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print (data.decode()) # client.close() |
直接把用户输入的内容发送给服务器。
执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#=========客户端======== >>你好 你好 >>中国 中国 >>hello world HELLO WORLD >> Process finished with exit code 1 #========服务器端========= b '\xe4\xbd\xa0\xe5\xa5\xbd' b '\xe4\xb8\xad\xe5\x9b\xbd' b 'hello world' Traceback (most recent call last): ... ConnectionResetError: [WinError 10054 ] 远程主机强迫关闭了一个现有的连接。 Process finished with exit code 1 |
可以看到这里已经实现了多少发送和接收的效果,但是如果客户端断开连接,服务器端也被迫中断。
在python2下如果客户端突然中断,服务器端并不会直接中断。
以下实验在Python2环境下。
单个客户端通信
服务器端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 最多可以挂起多少个连接 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#-*- coding=utf-8 -*- #客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = raw_input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print ( 'recv:' ,data.decode()) # client.close() |
开始通信:
首先客户端先发送数据:
在看服务器端接收:
发送接收正常。
现在用CTRL+c断开客户端之后服务器端的情况。
修改服务器端代码, 加一个统计,查看下什么时候开始死循环的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 count = 0 #统计 条件 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 count + = 1 if count > 10 : break server.close() |
客户端发送接收数据结果。
服务器端发送接收数据结果。
因为客户端断开,服务器端接收的都是空。
优化服务器端,断开就退出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) #客户端断开就退出 break conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端:
服务器端:
客户端断开,服务器直接退出。
多个客户端通信
怎么让服务器端一直保持接收状态呢?
想要 一直保持接收状态就要在客户端断开之后,继续执行server.accept()。
对的。在server.accept()之前在加一个while,当一个客户端断开了之后break,跳出最里层的循环的时候,又继续server.accept()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 while True : conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) break conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
修改并启动服务器端代码。
客户端1
客户端2
服务器端
断开客户端1之后:
服务器端
客户端2
简单的实现了能多个连接,但是只能同时跟一个客户端通信的功能。。
模拟SSH
既然可以发数据过来,那么也可以把这个数据做为命令执行。
首先修改服务器端,发送过来的命令执行并把结果返回给客户端。
服务器端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#-*-coding:utf-8 -*- import socket import os server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 while True : conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) break res = os.popen(data).read() conn.send(res) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#-*- coding=utf-8 -*- #客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = raw_input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print (data) # client.close() |
执行客户端
服务器端
这里是有返回的,如果一条命令的返回数据大于了定义的接收的大小,那么这次客户端接收的数据就不全,剩余的数据要等到服务器下次发送才能接收过来。比如定义的接收数据大小是1024,那么一次只能接收1024字节的数据。其余的数据都是在缓冲区里面。因为客户端不知道要接收几次。所以服务器端应该把本次要发送的数据大小先发过来,客户端就知道要接收几次了。
socket实现多个连接
前戏很重要~~
在实现多个连接之前,先实现下多次发送和接收数据。
如果要多次接收数据,那么在服务器端的接收和客户端的发送部分就必须使用循环。
以下代码在python3.5下运行。
服务器端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#服务器端 import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen() #监听 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print (data) conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端:
1 2 3 4 5 6 7 8 9 10 11 12 |
#客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print (data.decode()) # client.close() |
直接把用户输入的内容发送给服务器。
执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#=========客户端======== >>你好 你好 >>中国 中国 >>hello world HELLO WORLD >> Process finished with exit code 1 #========服务器端========= b '\xe4\xbd\xa0\xe5\xa5\xbd' b '\xe4\xb8\xad\xe5\x9b\xbd' b 'hello world' Traceback (most recent call last): ... ConnectionResetError: [WinError 10054 ] 远程主机强迫关闭了一个现有的连接。 Process finished with exit code 1 |
可以看到这里已经实现了多少发送和接收的效果,但是如果客户端断开连接,服务器端也被迫中断。
在python2下如果客户端突然中断,服务器端并不会直接中断。
以下实验在Python2环境下。
单个客户端通信
服务器端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 最多可以挂起多少个连接 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#-*- coding=utf-8 -*- #客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = raw_input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print ( 'recv:' ,data.decode()) # client.close() |
开始通信:
首先客户端先发送数据:
在看服务器端接收:
发送接收正常。
现在用CTRL+c断开客户端之后服务器端的情况。
修改服务器端代码, 加一个统计,查看下什么时候开始死循环的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 count = 0 #统计 条件 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 count + = 1 if count > 10 : break server.close() |
客户端发送接收数据结果。
服务器端发送接收数据结果。
因为客户端断开,服务器端接收的都是空。
优化服务器端,断开就退出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) #客户端断开就退出 break conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端:
服务器端:
客户端断开,服务器直接退出。
多个客户端通信
怎么让服务器端一直保持接收状态呢?
想要 一直保持接收状态就要在客户端断开之后,继续执行server.accept()。
对的。在server.accept()之前在加一个while,当一个客户端断开了之后break,跳出最里层的循环的时候,又继续server.accept()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#-*-coding:utf-8 -*- import socket server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 while True : conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) break conn.send(data.upper()) #发送数据,要发给谁就用谁的标记位 server.close() |
修改并启动服务器端代码。
客户端1
客户端2
服务器端
断开客户端1之后:
服务器端
客户端2
简单的实现了能多个连接,但是只能同时跟一个客户端通信的功能。。
模拟SSH
既然可以发数据过来,那么也可以把这个数据做为命令执行。
首先修改服务器端,发送过来的命令执行并把结果返回给客户端。
服务器端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#-*-coding:utf-8 -*- import socket import os server = socket.socket() server.bind(( 'localhost' , 6969 )) #绑定要监听的端口 server.listen( 1 ) #监听 while True : conn,address = server.accept() #等待接收数据 返回两个值,一个是对方的标记位,一个是对方的地址 while True : data = conn.recv( 1024 ) #接收数据,谁发数据给我就用谁的标记位接收 print ( 'recv:' ,data) if not data: print ( '客户端断开连接...' ) break res = os.popen(data).read() conn.send(res) #发送数据,要发给谁就用谁的标记位 server.close() |
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#-*- coding=utf-8 -*- #客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(( 'localhost' , 6969 )) while True : msg = raw_input ( '>>' ).strip() client.send(msg.encode( "utf-8" )) #发送数据 data = client.recv( 1024 ) #接收指定大小的字节 print (data) # client.close() |
执行客户端
服务器端
这里是有返回的,如果一条命令的返回数据大于了定义的接收的大小,那么这次客户端接收的数据就不全,剩余的数据要等到服务器下次发送才能接收过来。比如定义的接收数据大小是1024,那么一次只能接收1024字节的数据。其余的数据都是在缓冲区里面。因为客户端不知道要接收几次。所以服务器端应该把本次要发送的数据大小先发过来,客户端就知道要接收几次了。
感谢:https://www.cnblogs.com/qing-chen/p/7445085.html