python3 网络编程基础-socket TCP,UDP通信,远程终端

97 阅读2分钟

概念

服务端和客户端通信的过程:

服务端绑定一个端口,客户端连接到该端口进行通信。连接的时候,客户端会随机一个端口和服务端进行通信。

当接收数据为空的时候,此时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()