day32

今日总结:

server服务器

import socket
server = socket.socket()  # 获得ip类型,和规定的tcp协议
server.bind(("127.0.0.1", 1688))  # 绑定自己的ip地址和端口
server.listen()  # 监听
while True:  # 接待多个人
    client, addr = server.accept()  # 三次握手
    print("接到一个客人了,开始服务了!")
    # 循环收发数据(例如:这是接待一个人,这个人买好多种商品的时候)
    while True:
        try:  # 有可能recv接受数据出现问题,也有能发送数据出问题,所以try
            data = client.recv(1024).decode("utf-8")  # 接收数据       注意接受是客户收数据  直接进行转码
            if not data:  # 在这里要判断接受的数据是否为空,即客户端是否退出或者关闭程序
                break  # 如果为空则结束接受,断开链接
            print(data)
            #res = data[1:]
            # print(data.decode("utf-8"))  # 把接收到的数据转码
            client.send(res.encode("utf-8"))  # 发送数据     给客户端发数据
        except ConnectionResetError as e:  # 收发出问题就报这个错误    局部报错
            print("客户端挂了!", e)
            client.close()  # 报错断开链接
            break  # 结束循环
    client.close()  # 断开链接
   
   

client客户端

import socket
client = socket.socket()  # 获得ip类型和遵循的tcp协议
try:
    client.connect(("127.0.0.1", 1688))  # 连接服务器
    print("连接成功!")
    # 循环收发数据
    while True:
        msg = input(":")
        if msg == "q": break
        if not msg: continue
        client.send(msg.encode('utf-8'))  # 发送数据     只能发二进制数据
        data = client.recv(1024)  # 接收数据         收多少字节数
        print(data.decode("utf-8"))       #传过来的是二进制, 把二进制进行转码
    client.close()                     #如果连接服务器正常,发送正常,执行完后断开链接
except ConnectionRefusedError as e:  # 链接服务器出错,如果连接失败就走这个
    print("链接服务器失败!", e)
except ConnectionResetError as e:  # 如果收发出问题,此时就报这个错误,   收发失败就走这个
    print("服务器挂了!", e)
    client.close()  # 如果连接失败,就不会走下面的代码,同样收发出现问题,也不会走下面的代码,此时都未断开链接,处于等待状态,所以要断开链接
# except Exception as e:                               #万能异常
#     print("链接服务器失败!", e)
#     print(type(e))                                #<class 'ConnectionRefusedError'>

客户端思路:(基本循环模板)

                 1,先编写最基本完整数据结构

                  2,循环发收数据,首先判断发送的数据是否为空或退出

                                                   把发送的数据进行转码为二进制

                                                   把收到的二进制数据进行转码

                 3,连接服务器和收发数据时无法预知哪里出现问题和阻塞,

                       所以在连接服务器之前使用 try,保证机器不蹦

                                          1》,链接服务器失败       except ConnectionRefusedError as e:

                                           2》,发收数据阻塞报错 即服务器挂了,    except ConnectionResetError as e:

                                                     (except Exception as e:                               #万能异常)

服务端思路:(基础循环模板)

                   1,先编写最基本完整的服务数据结构(1:导入接口2:ip类型和规定tcp协议server=socket.socket

                               3:绑定本机ip和端口bind,4:监听listen5:建立连接accept,三次握手6:接受数据revc

                               7:发送数据send 8:断开链接 client.close() ,注意,收发数据都是客户端即client.revc和client.send,并且注    意进制转码。)

         2,循环收发数据,首先判断接收的数据是否为空

                                                    把接受到的二进制数据进行转码,你才能看懂

                                                    把发送的数据进行二进制转码

                     3,收发数据时无法预知哪里出现问题和阻塞

                                       所以在收发数据之前使用 try,即三次保证机器不蹦  

                     4,循环接受数据,例:即接完一个客户后继续接下一个客户            

                                        在三次握手之前

                      5,报错信息:except ConnectionResetError as e:  # 收发出问题就报这个错误    局部报错

                                               print("客户端挂了!", e)

                                                       break  # 结束循环               client.close()  # 断开链接

server服务器中的listen监听中的参数:

import socket
server = socket.socket()
server.bind(("127.0.0.1", 1688))
server.listen(5)
# 5就是最大半连接数   本质就是一个数组,未完成的就会被加入到数组中
# 每一次执行accept 就会挑出一个来完成三次握手,如果达到最大限制,额外的就会被直接拒绝
# 我们可以调整内核参数来修改 最大等待时长,如果超时,客户还是没有回复第三次握手信息,就直接删除

粘包问题

import socket
import subprocess

server = socket.socket()

server.bind(("127.0.0.1",1589)) #必须为元组
server.listen()

while True:
client,addr = server.accept()
print("客户端连接成功,开始")
while True:
try:
data = client.recv(1024).decode("utf-8") # 接收数据
if not data:
break
print(data)
#第一个参数填的是指令 shell=True,第三个是管道,输出管道和错误管道
# 要建管道,把数据丢进管道,不然的话数据就会出现在屏幕终端
p = subprocess.Popen(data,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# 读数据 不要先读err信息,它会卡住 原因不详 linux不会有问题,例如tasklist列出任务列表,netstat-ano 啥的都不行
data = p.stdout.read()
err_data = p.stderr.read()
# 返回的结果就是二进制,所以不需要进行转码
client.send(data + err_data ) # 发送数据
# client.close()
except ConnectionResetError as e:
print("客户端挂了!",e)
client.close()
break
client.close()
 待续。。。。。。。。。。。。。
 
 
原文地址:https://www.cnblogs.com/Fzhiyuan/p/10947034.html