1.socket里面的,AF_INET和AF_UNIX有什么区别?
- AF_INET用于真实的两台机器进行通信。
- AF_UNIX用于本地自己跟自己通信。
- 参考资料:http://www.langdebuqing.com/
2.socket 通信示例?
- 服务端:
- 代码:
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET和AF_UNIX区别,AF_INET远程交互,AF_UNIX本地交互 # SOCK_STREAM 流式协议 = TCP ; SOCK_DGRAM 数据报协议 = UDP print(phone) # <socket.socket fd=436, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0> # 2.绑定电话卡 phone.bind(("127.0.0.1",8080)) # 绑定ip和端口 # 为了让客户端访问,这里一般固定后就不变了. # 3.开机 phone.listen(5) # __backlog = 5 半连接池数量为5 # 4.接受链接信息 conn,client_addr = phone.accept() # 返回两个值. conn是链接通路,是三次握手的成果;client_addr是客户端的地址. print(conn) #<socket.socket fd=356, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, # laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 1873)> print(client_addr) # ('127.0.0.1', 1873) # 5.收发消息 data = conn.recv(1024) # 最大接收字节数 1024 ; 注意 这里的data是byte类型 print(data) # b'hello' conn.send(data.upper()) # 回消息 ,这里为了演示,把data的大写返回去。 # 6.挂电话 conn.close() # 7.关机 phone.close()
- 客户端:
- 代码:
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET和AF_UNIX区别,AF_INET远程交互,AF_UNIX本地交互 # SOCK_STREAM 流式协议 = TCP ; SOCK_DGRAM 数据报协议 = UDP # 2. 打电话 phone.connect(("127.0.0.1",8080)) # 3.发,收数据 phone.send("hello".encode("utf-8")) # phone.send(b"hello") # 这样也可以 data = phone.recv(1024) # 接收数据 同样设置为1024 print(data.decode("utf-8")) # 返回的也是byte类型,需要解码 # 4.关机 phone.close()
3.socket通信,升级--加上循环。
- 服务端:
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2.绑定电话卡 phone.bind(("127.0.0.1",8080)) # 3.开机 phone.listen(5) # 4.接受链接信息 conn,client_addr = phone.accept() # 返回两个值. conn是链接通路,是三次握手的成果;client_addr是客户端的地址. # 5.收发消息 while True: data = conn.recv(1024) # 最大接收字节数 1024 ; 注意 这里的data是byte类型 print(data) # b'hello' conn.send(data.upper()) # 回消息 ,这里为了演示,把data的大写返回去。 # 6.挂电话 conn.close() # 7.关机 phone.close()
-
- 客户端:
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET和AF_UNIX区别,AF_INET远程交互,AF_UNIX本地交互 # SOCK_STREAM 流式协议 = TCP ; SOCK_DGRAM 数据报协议 = UDP # 2. 打电话 phone.connect(("127.0.0.1",8080)) # 3.发,收数据 # 建立循环 while True: msg = input("请输入信息:") phone.send(msg.encode("utf-8")) data = phone.recv(1024) # 接收数据 同样设置为1024 print(data.decode("utf-8")) # 返回的也是byte类型,需要解码 # 4.关机 phone.close()
-
4.socket通信--升级2--解决客户端发空报错。
- 服务端代码不动:
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2.绑定电话卡 phone.bind(("127.0.0.1",8080)) # 3.开机 phone.listen(5) # 4.接受链接信息 conn,client_addr = phone.accept() # 返回两个值. conn是链接通路,是三次握手的成果;client_addr是客户端的地址. # 5.收发消息 while True: data = conn.recv(1024) # 最大接收字节数 1024 ; 注意 这里的data是byte类型 print(data) # b'hello' conn.send(data.upper()) # 回消息 ,这里为了演示,把data的大写返回去。 # 6.挂电话 conn.close() # 7.关机 phone.close()
-
- 客户端--增加为空判断
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 打电话 phone.connect(("127.0.0.1", 8080)) # 3.发,收数据 # 建立循环 while True: msg = input("请输入信息:") if len(msg) == 0: continue # 跳过本次 phone.send(msg.encode("utf-8")) # print("1111111111") 调试1 data = phone.recv(1024) # 接收数据 # 发空消息,会阻塞这里 # print("222222222") 调试2 print(data.decode("utf-8")) # 4.关机 phone.close()
-
5.服务端,应该具备的能力是?
- 一直提供服务
- 并发的能力
6.socket通信--升级3--解决服务端一直接受“空”问题。
- 服务端:
- 增加长度判断
- 代码:
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2.绑定电话卡 phone.bind(("127.0.0.1",8080)) # 3.开机 phone.listen(5) # 4.接受链接信息 conn,client_addr = phone.accept() # 返回两个值. conn是链接通路,是三次握手的成果;client_addr是客户端的地址. # 5.收发消息 while True: try: # win 其他版本, 会报错 data = conn.recv(1024) if len(data) == 0: # linux win11 会收到空 b'' break print(data) # b'hello' conn.send(data.upper()) except Exception: break # 6.挂电话 conn.close() # 7.关机 phone.close()
- 客户端:
-
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 打电话 phone.connect(("127.0.0.1", 8080)) # 3.发,收数据 # 建立循环 while True: msg = input("请输入信息:") if len(msg) == 0: continue # 跳过本次 phone.send(msg.encode("utf-8")) # print("1111111111") 调试1 data = phone.recv(1024) # 接收数据 # 发空消息,会阻塞这里 # print("222222222") 调试2 print(data.decode("utf-8")) # 4.关机 phone.close()
-
7.socket通信--升级4--解决服务端只能提供一次服务。
- 想让服务端一直提供服务。
- 服务端:
- 增加循环。
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2.绑定电话卡 phone.bind(("127.0.0.1", 8080)) # 3.开机 phone.listen(5) # 4.接受链接信息 # 循环执行 while True: conn, client_addr = phone.accept() # 5.收发消息 while True: try: # win 其他版本, 会报错 data = conn.recv(1024) if len(data) == 0: # linux win11 会收到空 b'' break print(data) # b'hello' conn.send(data.upper()) except Exception: break # 6.挂电话 conn.close() # 7.关机 phone.close()
- 客户端:
- 代码:
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 打电话 phone.connect(("127.0.0.1", 8080)) # 3.发,收数据 # 建立循环 while True: msg = input("请输入信息:") if len(msg) == 0: continue # 跳过本次 phone.send(msg.encode("utf-8")) # print("1111111111") 调试1 data = phone.recv(1024) # 接收数据 # 发空消息,会阻塞这里 # print("222222222") 调试2 print(data.decode("utf-8")) # 4.关机 phone.close()
8.如何写一个执行远程命令的C/S程序?
- 服务端--调用subprocess来执行
-
import socket import subprocess # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2.绑定电话卡 phone.bind(("127.0.0.1", 8080)) # 3.开机 phone.listen(5) # 4.接受链接信息 # 循环执行 while True: conn, client_addr = phone.accept() # 5.收发消息 while True: try: # win 其他版本, 会报错 cmd = conn.recv(1024) if len(cmd) == 0: # linux win11 会收到空 b'' break cmd = cmd.decode("utf-8") # 先解码 # 再执行 obj = subprocess.Popen(cmd,shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE ) res1 = obj.stdout.read() res2 = obj.stderr.read() conn.send(res1+res2) # 把两个值都返回去 except Exception: break # 6.挂电话 conn.close() # 7.关机 phone.close()
- 客户端--注意解码方式(win用gbk,linux用utf-8)
-
import socket # 1.买手机 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 打电话 phone.connect(("127.0.0.1", 8080)) # 3.发,收数据 # 建立循环 while True: msg = input("请输入信息:") if len(msg) == 0: continue # 跳过本次 phone.send(msg.encode("utf-8")) data = phone.recv(1024) # 接收数据 # 发空消息,会阻塞这里 print(data.decode("gbk")) # 在win解码用gbk # 4.关机 phone.close() # !!!注意,这里输入tasklist会出现不全。输入dir可以展示
- 问题1,是输入tasklist会出现显示不全的现象。
- 问题2,是输入tasklist后再输入dir会发现显示的上次剩余的内容。(这可以帮助理解【流协议】)
- 我的解决:可以尝试recv(1024) -->recv(更大的数字)
参考资料:
标签:socket,phone,--,AF,Python,print,data,conn From: https://www.cnblogs.com/liqi175/p/17152125.html