zoukankan      html  css  js  c++  java
  • socket套接字

    一、复习
    1、网络编程
    软件开发架构
    b/s架构
    c/s架构
    本质都是c/s架构
    2、互联网协议
    OSI七层协议
    应用层
    表示层
    会话层
    传输层
    网络层
    数据链路层
    物理连接层
    3、 物理连接层:建立物理连接传输电信号
    数据链路层(以太网协议)
    规定了电信号的分组方式
    任何接入互联网的计算机都必须有一块网卡(有一个独一无二的编号:mac地址)
    交换机:基于以太网通信特点:靠吼(一旦同时有好多电脑发送请求,交换机吼的话就会产生广播风暴)
    网络层(ip协议):
    规定了任何接入互联网的一台计算机都必须有一个ip地址(点分十进制)
    传输层(TCP,UDP)
    tcp,udp基于端口工作的协议
    端口范围:0~65535
    端口:能够标识一台计算机上某一时刻运行的某一款应用程序
    ip+port就能够标识世界上唯一一台计算机上运行的某一款基于互联网通信的软件
    TCP(流式协议,可靠协议):三次握手,四次挥手
    UDP(数据报协议):
    无需建立双向连接,并且传输数据不可靠,可能会出现丢包的情况
    通信速度比较快,但是发送的数据不会在内存中保留
    应用层:
    http协议,ftp协议

    二、socket(套接字)
    1、基于socket实现客户端与服务端通信
    服务端:
      
    import socket

    server = socket.socket() #产生服务的对象
    server.bind(('127.0.0.1',8080)) #绑定自己的ip+port
    server.listen(5) # 半连接池 #允许的最大请求数(开客户端的次数)


    conn,addr = server.accept() #等待接收,conn是类的对象,addr是客户端那个人的地址


    data = conn.recv(1024) #接收客户端发送的信息
    print(data)
    conn.send(b'hello') #回复信息

    conn.close() #关闭通信连接
    server.close() #关闭服务端
    客户端:
    import socket

    client = socket.socket() #产生客户端对象(不传参数的话,默认tcp协议)
    client.connect(('127.0.0.1',8080)) #找到服务器的ip+port

    client.send(b'how are you ') #向服务端发送信息
    data = client.recv(1024) #接收服务端回复的信息
    print(data)
    client.close() #关闭通信连接
    2、tcp协议的特点:
    如果客户端发来(‘hello’)
    服务端:
    conn,addr = server.accept()
    data = conn.recv(4) #只能接收4个字节
    print(data) #b'hell'
    data = conn.recv(5) #带着第一次遗留的接收5个字节
    print(data) #b'ohell'
    data = conn.recv(5) #带着第二次遗留的接收5个字节
    print(data) #b'ohell'
    3、最终解决粘包问题
    服务端:
    import socket
    import subprocess
    import struct
    import json


    server = socket.socket()
    server.bind(('127.0.0.1',8098))
    server.listen(5)

    while True:
    conn,addr = server.accept()
    while True:
    try: # 当客户端人为断掉后,服务端会报错,需要捕捉异常
    data = conn.recv(1024).decode('utf-8')
    if len(data) == 0:break #针对Linux和Mac系统,客户端异常断开反复收空的情况
    obj = subprocess.Popen(data,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    stdout = obj.stdout.read()
    stderr = obj.stderr.read() # 接收客户端发送过来的指令
    print(len(stdout+stderr))

    header_dic = {
    'filename':'cls.txt',
    'len':len(stdout+stderr) # 制作自定义的字典,可以自己添加信息
    }
    header_bytes = json.dumps(header_dic).encode('utf-8')

    # 制作报头
    header = struct.pack('i',len(header_bytes)) # 将需要发送给客户的数据打包成固定4个字节
    conn.send(header) # 先发报头
    conn.send(header_bytes) #再发字典
    conn.send(stdout+stderr) #再发真实数据内容
    except ConnectionResetError:
    break
    conn.close()
    server.close()

    客户端:
    import socket
    import struct
    import json


    client = socket.socket()
    client.connect(('127.0.0.1',8098))


    while True:
    msg = input('>>>:').encode('utf-8')
    if len(msg) == 0:continue
    client.send(msg)
    header = client.recv(4) # 接收报头

    # 对这个头进行解包,获取真实数据的长度
    head_len = struct.unpack('i',header)[0]
    head_dic = json.loads(client.recv(head_len).decode('utf-8'))
    print(head_dic)

    # 对需要接收的数据进行循环接收
    total_size = head_dic['len']
    recv_size = 0
    res = b''
    while recv_size < total_size:
    data = client.recv(1024)
    res += data
    recv_size += len(data)
    print(res.decode('gbk'))
  • 相关阅读:
    常用256安全色
    PHP获取中英文混合字符串的字数
    windows 2012 443端口无法访问解决随记!
    SQL提取时间段内数据
    正则表达式匹配
    PclZip library能够压缩与解压缩Zip格式
    安装IIS或证书上服务提示安装程序无法复制文件 ftpsvc2.dl的解决办法
    tomcat
    版本控制gitlab
    rsync
  • 原文地址:https://www.cnblogs.com/yanminggang/p/10797744.html
Copyright © 2011-2022 走看看