day26
网络通信
参考:
男生是client端,字条是socket(sk),通过sk通信。
socket属于客户端。应用程序两端通过“套接字”向网络发出请求或者应答网络请求。可以把socket理解为通信的把手(hand)。
确定对端IP地址→ 确定应用程序端口 → 确定通讯协议
server下的方法
bind()
listen()
accept()
recv()
send()#传送内容必须为bytes类型
sendall()
close()
client下的方法
connect()
recv()
send()
aendall()
close()
client发送,serve接收
serve.py
1 importsocket2
3 sk = socket.socket()#创建socket
4
5 print(sk)6
7 address = ('127.0.0.1', 8000)#本机地址
8 sk.bind(address)#为socket绑定IP和端口号
9
10 sk.listen(3)#限制排队的个数
11 print('waiting......')12 conn, addr = sk.accept()#conn为客户端socket对象
13 #14 #inp = input('>>>')
15 #conn.send(bytes(inp, 'utf8'))
16
17 data = conn.recv(1024)#为什么用conn,而不用sk
18 print(str(data, 'utf8'))19
20 #conn.close()#关具体对象
21 #sk.close()#全关
client.py
1 importsocket2
3 sk =socket.socket()4
5 print(sk)6 address = ('127.0.0.1', 8000)7
8 sk.connect(address)9
10 #data = sk.recv(1024)#收到的为bytes类型
11 data = sk.send(bytes('hah', 'utf8'))12
13 #print(str(data, 'utf8'))
运行serve.py
waiting......
waiting,accept()阻塞。
运行client.py
Process finished with exit code 0
serve收到数据“hah”
waiting......
hah
Process finished with exit code 0
client接收,serve发送
serve.py
1 importsocket2
3 sk = socket.socket()#创建socket
4
5 print(sk)6
7 address = ('127.0.0.1', 8000)#本机地址
8 sk.bind(address)#为socket绑定IP和端口号
9
10 sk.listen(3)#限制排队的个数
11 print('waiting......')12 conn, addr = sk.accept()#conn为客户端socket对象
13
14 inp = input('>>>')15 conn.send(bytes(inp, 'utf8'))16
17 #data = conn.recv(1024)#为什么用conn,而不用sk
18 #print(str(data, 'utf8'))
19
20 #conn.close()#关具体对象
21 #sk.close()#全关
client.py
importsocket
sk=socket.socket()print(sk)
address= ('127.0.0.1', 8000)
sk.connect(address)
data= sk.recv(1024)#收到的为bytes类型#data = sk.send(bytes('hah', 'utf8'))
print(str(data, 'utf8'))
运行serve.py
waiting......
运行client.py
在serve命令行输入hello
waiting......>>>hello
Process finished with exit code 0
client命令行收到数据。
hello
Process finished with exit code 0
不间断聊天
client.py
1 importsocket2
3 sk =socket.socket()4
5 print(sk)6 address = ('127.0.0.1', 8000)7 sk.connect(address)8
9 whileTrue:10 inp = input('>>>')11 if inp == 'exit':12 break
13 sk.send(bytes(inp, 'utf8'))14
15 data = sk.recv(1024)16 print(str(data, 'utf8'))17
18 sk.close()19 #print(sk)
serve.py
1 importsocket2
3 sk = socket.socket()#创建socket
4
5 print(sk)6
7 address = ('127.0.0.1', 8000)#本机地址
8 sk.bind(address)#为socket绑定IP和端口号
9
10 sk.listen(3)#限制排队的个数
11 print('waiting......')12 #conn, addr = sk.accept()#conn为客户端socket对象
13
14 whileTrue:15 conn, addr =sk.accept()16 print(addr) #client打开则接收
17 whileTrue:18 #收
19 try:20 data = conn.recv(1024)#为什么用conn,而不用sk,client关闭时报错误
21 exceptException:22 break #client端停止,他也停止
23 print('.......',str(data, 'utf8'))24 if not data:break
25 #发
26 inp = input('>>>')27 conn.send(bytes(inp, 'utf8'))28
29 sk.close()#全关
不间断聊天,其中client若关闭,新开一个client,serve端还能继续服务。
粘包现象(远程执行命令)
cmd_client.py
1 importsocket2
3 sk =socket.socket()4
5 print(sk)6 address = ('127.0.0.1', 8001)7 sk.connect(address)8
9 whileTrue:10 inp = input('>>>')11 if inp == 'exit':12 break
13 sk.send(bytes(inp, 'utf8'))14 result_len = int(str(sk.recv(1024), 'utf8'))15
16 sk.sendall(bytes('ok', 'utf8'))#收到长度信息后,告诉server
17
18 data = bytes()#初始化
19 while len(data) != result_len: #等于原文件大小,说明接收完
20 recv = sk.recv(1024)21 data +=recv22
23 print(str(data, 'utf8'))24
25 sk.close()26 #print(sk)
cmd_server.py
1 importsocket2 importsubprocess3 sk = socket.socket()#创建socket
4
5 print(sk)6
7 address = ('127.0.0.1', 8001)#本机地址
8 sk.bind(address)#为socket绑定IP和端口号
9
10 sk.listen(3)#限制排队的个数
11 print('waiting......')12 #conn, addr = sk.accept()#conn为客户端socket对象
13
14 whileTrue:15 conn, addr =sk.accept()16 print(addr) #client打开则接收
17 whileTrue:18 #收
19 try:20 data = conn.recv(1024)#为什么用conn,而不用sk,client关闭时报错误
21 exceptException:22 break #client端停止,他也停止
23 print('.......',str(data, 'utf8'))24
25 if not data:break
26 obj = subprocess.Popen(str(data, 'utf8'), shell = True, stdout =subprocess.PIPE)27 cmd_result = obj.stdout.read()#以上执行结果
28 #print(cmd_result)
29 result_len = bytes(str(len(cmd_result)), 'utf8')30
31
32 conn.sendall(result_len)#发
33 #先向client发送数据,client若收到则向server发送OK,Server再发送处理结果
34 #若连续发送,两个发送内容(长度,处理结果)可能会合并。
35 re = conn.recv(1024)#防止粘包
36 if str(re, 'utf8') != 'ok':37 break
38 #发
39 conn.sendall(cmd_result)40
41 #conn.sendall(result_len) # 这种方式会发生粘包现象,长度和内容合在一起了
42 #conn.sendall(cmd_result)
43 sk.close()#全关
先执行server.py,再执行client.py,在client中输入命令(dir,pwd,ifconfig等)