书写基于tcp协议的套接字程序

ARP协议的通信原理:
同一局域网下
将自己的IP地址与子网掩码进行按位与运算,得到子网地址,将对方的IP地址与子网掩码进行按位与运算,
得到对方的子网地址,一旦双方的子网地址一模一样,ARP会将原Mac地址加12位ff:ff:ff:ff:ff:ff加原IP地址加目标IP地址
发给局域网下的每一个计算机,计算机进行比对,若与目标IP一致,会将自己MAC地址返回给ARP,若目标IP与自己IP不一致则丢弃
ff:ff:ff:ff:ff:ff 表示为获取目标IP的MAC地址的信号

不同局域网
若原主机与目标主机不在局域网下,ARP会将网关的Mac地址获取到,原主机将数据发给网关,此时ARP发的就是原IP地址,原MAC地址,12个f,加网关的IP地址由网关等一些网络设备传输
到目标主机上,此时原主机获取的就是网关的Mac地址,然后原主机开始发送真实数据,此时原主机发的是原主机IP地址,加目标主机的IP地址由网关处理转发,数据返回时也是通过网关将数据返回到原主机上

服务端套接字程序 将程序通信模拟成打电话

import  socket
#买手机
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)    #sock_stream    流式协议
#绑定电话卡
phone.bind(('127.0.0.1',8080))
#开机
phone.listen(5)
#接收链接请求
conn, client_addr = phone.accept()
#收发消息
while True:
    data = conn.recv(1024)      #最大接收的字节数
    conn.send(data.upper())
#挂电话
conn.close()
#关机
phone.close()

以上服务器运行完之后,在重启的时候可能会遇到端口已被占用的问题,此时的解决方案为:
一:需要更换端口号,同时更换服务端端口号
二:加入一条socket配置,重用ip和端口,代码如下:

phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080))

客户端套接字程序(基于tcp协议)

import socket
#买手机
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#打电话
phone.connect(("127.0.0.1",8080))
#收发数据
while True:
    msg = input(">>>:").strip()
    phone.send(msg.encode("utf-8"))
    data = phone.recv(1024)
    print(data.decode("utf-8"))
#关机
phone.close()

如果遇到客户端单方面解除链接,会导致客户端阻塞在原地,同时服务端也会停留在原地,因为这种异常是不可控的,
所以此时可以用try…except:…进行补救,让服务端不崩代码如下:

import  socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
while True:
    conn, client_addr = phone.accept()
    while True:
        try:
            data = conn.recv(1024)
            conn.send(data.upper())
        except Exception:
            break
    conn.close()
phone.close()

以上代码虽然解决了客户端单方面解除链接的问题,但仍然无法抗并发,一次只能服务一个客户端,显然这是不合理的,抗并发在后续会补充

#编写远程执行命令的程序:服务端(tcp协议)代码如下:

import  socket
import subprocess
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
while True:
    conn, client_addr = phone.accept()
    while True:
        try:
            data = conn.recv(1024)
            cmd = data.decode("utf-8")
            obj = subprocess.Popen(cmd,shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
            res1 =obj.stdout.read()
            res2 = obj.stderr.read()
            conn.send(res1+res2)
        except Exception:
            break
    conn.close()
phone.close()

客户端套接字程序(基于tcp协议)

import socket
#买手机
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#打电话
phone.connect(("127.0.0.1",8080))
#收发数据
while True:
    msg = input(">>>:").strip()
    phone.send(msg.encode("utf-8"))
    data = phone.recv(1024)
    print(data.decode("utf-8"))
#关机
phone.close()

猜你喜欢

转载自blog.csdn.net/givenchy_yzl/article/details/112686979