概念
服务端和客户端通信的过程:
服务端绑定一个端口,客户端连接到该端口进行通信。连接的时候,客户端会随机一个端口和服务端进行通信。
当接收数据为空的时候,此时socket断开连接。
客户端
import socket
def main():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 8080)) # 注意是一个参数,参数是一个元组,包含IP和端口,如果只保留一个括号就变成了2个参数
client.send("你好".encode("utf-8"))
data = client.recv(1024)
print(data.decode("utf-8"))
client.close()
if __name__ == "__main__":
main()
服务端
import socket
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("0.0.0.0", 8080))
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
server.listen(100)
client, (ip, port) = server.accept()
data = client.recv(1024)
print(data.decode("utf-8"))
new_data = "一共发了" + str(len(data.decode("utf-8"))) + "个字符"
client.send(new_data.encode("utf-8"))
client.close()
if __name__ == "__main__":
main()
UDP通信
UDP是不可靠的通信,在网络传输的过程中,如果数据发送失败,则不会重发,TCP如果网络传输失败,会继续重发。通常用于一些对可靠性要求不高的网络中,比如视频通讯。
客户端
import socket
def main():
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto("hello world".encode("utf-8"), ("127.0.0.1", 8080))
data, (ip, port) = client.recvfrom(1024)
print(data)
client.close()
if __name__ == "__main__":
main()
服务端
import socket
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(("0.0.0.0", 8080))
# recv只能接受数据,无法获取目标的IP和端口,因此不能往该客户端发送消息
# data = server.recv(1024)
# 此方法可以同时接收数据和获取客户端的IP和端口号
data, (ip, port) = server.recvfrom(1024)
new_data = format("从%s:%s 接收了%d个字符" % (ip, port, len(data.decode("utf-8"))))
server.sendto(new_data.encode("utf-8"), (ip, port))
if __name__ == "__main__":
main()
远程终端
通过socket进行执行远程命令。
客户端
from socket import *
import struct
client = socket(AF_INET, SOCK_STREAM)
client.connect(("127.0.0.1", 8081))
while True:
msg = input("请输入命令>>").strip()
if len(msg) == 0: continue
client.send(msg.encode("utf-8"))
res = client.recv(4)
size = struct.unpack("i", res)[0]
all_data = b''
read_size = 0
while True:
if size - read_size > 1024:
data = client.recv(1024)
else:
data = client.recv(size-read_size)
read_size += len(data)
all_data += data
if size == read_size:
print(all_data.decode("utf-8"))
break
服务端
from socket import *
import subprocess
import struct
server = socket(AF_INET, SOCK_STREAM)
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
server.bind(("0.0.0.0", 8081))
server.listen(5)
while True:
client, (ip, port) = server.accept()
while True:
try:
data = client.recv(1024)
res = subprocess.Popen(data.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
success_result = res.stdout.read()
error_result = res.stderr.read()
all_data = success_result + error_result;
size = len(all_data)
header = struct.pack("i", size)
client.send(header)
client.send(all_data)
except Exception:
break
client.close()
socketserver 实现并发- TCP
服务端
import socketserver
class MySocketHandler(socketserver.BaseRequestHandler):
def handle(self):
print(self.request)
print(self.client_address)
while True:
data = self.request.recv(1024)
if len(data) == 0:
break
self.request.send(data.upper())
self.request.close()
def main():
server = socketserver.ThreadingTCPServer(("127.0.0.1", 9000), MySocketHandler)
server.serve_forever()
if __name__ == "__main__":
main()
客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 9000))
while True:
data = input("输入内容").strip()
if len(data) == 0: break
client.send(data.encode("utf-8"))
data = client.recv(1024)
print(data.decode("utf-8"))
client.close()
socketserver 实现并发- UDP
import socket
if __name__ == "__main__":
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.connect(("127.0.0.1", 9000))
while True:
data = input("输入内容").strip()
if len(data) == 0:
break
client.send(data.encode("utf-8"))
data = client.recv(1024)
print(data.decode("utf-8"))
client.close()
import socketserver
class MySocketHandler(socketserver.BaseRequestHandler):
def handle(self):
data = self.request[0]
server = self.request[1]
addr = self.client_address
print(self.client_address)
server.sendto(data.upper(), addr)
def main():
server = socketserver.ThreadingUDPServer(("127.0.0.1", 9000), MySocketHandler)
server.serve_forever()
if __name__ == "__main__":
main()