zoukankan      html  css  js  c++  java
  • 进军的socket

    在学socket有时候我们会遇到这种问题:

    解决方法一:

    在服务端中加入:severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    #!/urs/bin/evn python
    # -*- coding:utf-8 -*-
    import socket
    severTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    severTCP.bind(("127.0.0.1", 8888))  # 绑定端口
    severTCP.listen(5)           # 监听
    print("starting....")
    client, address = severTCP.accept()  # 等待连接
    while True:  # 通信循环
        data = client.recv(1024)  # 单位:byte. 1024代表最大接收1024个byte,收数据
        print("来%s客服端的数据" % client, data.decode("utf-8"))
        client.send(data.upper())  # 发数据
    client.close()
    severTCP.close()

    方法二:

    发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,
    vi /etc/sysctl.conf
    
    编辑文件,加入以下内容:
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 30
     
    然后执行 /sbin/sysctl -p 让参数生效。
     
    net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
    
    net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
    
    net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
    
    net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
    View Code
    客户端发送空,卡住,主要是在原因:缓冲区为空,recv就卡住:

    服务端:

     

    #!/urs/bin/evn python
    # -*- coding:utf-8 -*-
    import socket
    clientTCP = socket.socket(socket.AF_INET,
                              socket.SOCK_STREAM)
    clientTCP.connect(("127.0.0.1", 8888))
    while True:
        msg = input(">>:").strip()
        if not msg:continue
        # if len(msg)==0:continue
        clientTCP.send(msg.encode("utf-8"))
        data = clientTCP.recv(1024)
        print(data.decode("utf-8"))
    clientTCP.close()

     

     

     结果:

    客户端

    服务端:

     

     当客户端异常断开连接,看见服务端:

    Liunx :

    #!/urs/bin/evn python
    # -*- coding:utf-8 -*-
    import socket
    severTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    severTCP.bind(("127.0.0.1", 8888))  # 绑定端口
    severTCP.listen(5)           # 监听
    print("starting....")
    client, address = severTCP.accept()  # 等待连接
    while True:  # 通信循环
        data = client.recv(1024)  # 单位:byte. 1024代表最大接收1024个byte,收数据
        if not data: break   # 针对Liunx
        # if len(data): break
        print("来%s客服端的数据" % client, data.decode("utf-8"))
        client.send(data.upper())  # 发数据
    client.close()
    severTCP.close()
    View Code

    windows:

    #!/urs/bin/evn python
    # -*- coding:utf-8 -*-
    import socket
    severTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    severTCP.bind(("127.0.0.1", 8888))  # 绑定端口
    severTCP.listen(5)           # 监听
    print("starting....")
    client, address = severTCP.accept()  # 等待连接
    while True:  # 通信循环
        try:
            data = client.recv(1024)  # 单位:byte. 1024代表最大接收1024个byte,收数据
            print("来%s客服端的数据" % client, data.decode("utf-8"))
            client.send(data.upper())  # 发数据
        except ConnectionResetError:
            break
    client.close()
    severTCP.close()

    结果:

    客户端

     

     服务端:

     

     实现服务端对多个客户端服务(但这没有并发结果)

    #!/urs/bin/evn python
    # -*- coding:utf-8 -*-
    import socket
    severTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    severTCP.bind(("127.0.0.1", 8888))  # 绑定端口
    severTCP.listen(5)           # 监听
    print("starting....")
    while True:
        client, address = severTCP.accept()  # 等待连接
        while True:  # 通信循环
            try:
                data = client.recv(1024)  # 单位:byte. 1024代表最大接收1024个byte,收数据
                if not data:break  # Liunx
                print("来%s客服端的数据" % client, data.decode("utf-8"))
                client.send(data.upper())  # 发数据
            except ConnectionResetError:
                break
        client.close()
    severTCP.close()
    View Code

     

     一个简单聊天功能:

    服务端:

    #!/urs/bin/env python
    # -*- coding:utf-8 -*-
    import socket
    
    sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock_server.bind(("127.0.0.1", 8888))
    sock_server.listen(1)  # 开始监听,1代表在允许有一个连接排队,更多的新连接连进来时就会被拒绝
    while True:
        conn, addr = sock_server.accept()  # 阻塞直到有连接为止,有了一个新连接进来后,就会为这个请求生成一个连接对象
    
       print("新人来了", conn.getpeername())

       with conn:
    print('Connected by', addr) while True: try: data = conn.recv(1024) # 接收1024个字节 print("recv from zq:", conn.getpeername(), data.decode()) if not data: break # 收不到数据,就break response = input(">>>").strip() conn.send(response.encode("utf-8")) #print("send to xqx:", response) except ConnectionResetError: break conn.close() sock_server.close()

    客户端:

    #!/urs/bin/evn python
    # -*- coding:utf-8 -*-
    import socket
    clientTCP = socket.socket(socket.AF_INET,
                              socket.SOCK_STREAM)
    clientTCP.connect(("127.0.0.1", 8888))
    while True:
        msg = input(">>:").strip()
        if not msg:continue
        # if len(msg)==0:continue
        clientTCP.send(msg.encode("utf-8"))
        data = clientTCP.recv(1024)
        print('xqx',data.decode("utf-8"))
    clientTCP.close()

    结果:

    客户端

    服务端

    文件传输:

    #! /urs/bin/evn python
    # -*- coding:utf-8 -*-
    import socket
    import struct
    import json
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # tcp协议
    # 链接服务端
    phone.connect(("127.0.0.1", 8083))
    # 发,收消息
    while True:
        # 1 发命令
        cmd = input(">>>:").strip()
        if not cmd:continue
        phone.send(cmd.encode("utf-8"))  #
        # 2 以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户端
        # 第一步:先收报头长度
        obj = phone.recv(4)
        header_size = struct.unpack("i", obj)[0]
        # 第二步:再收报头
        header_bytes = phone.recv(header_size)
        # 第三步:从报头中解析出对真实数据的描述信息(数据的长度)
        header_json = header_bytes.decode("utf-8")
        heade_dic = json.loads(header_json)
        print(heade_dic)
        total_size = heade_dic["file_size"]
        # 第四步:接收真实数据
    
        filename = heade_dic["filename"]
        with open(filename, "wb") as f:
            recv_size = 0
            while recv_size < total_size:
                line = phone.recv(1024)  # 收。接命令
                f.write(line)
                recv_size += len(line)
    
    # 关闭
    phone.close()
    View Code
    #! /urs/bin/evn python
    # -*- coding:utf-8 -*-
    import socket
    import struct
    import json
    import os
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # tcp协议
    phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定ip和端口
    phone.bind(("127.0.0.1", 8083))
    # 监听
    phone.listen(5)
    print("statting....")
    # 等待链接
    while True:  # 链接循环。这里暂时没有并发功能
        conn, client_add = phone.accept()
        # 这一步对应客服端connect
        print(client_add)
        while True:  # 通信循环
            try:
                # 1 收命令
                res = conn.recv(8192)
                # 单位:byte. 1024代表最大接收1024个byte
                if not res: break
                # 针对异常后(liunx客服端强行停机后,服务端进入死循环,只适用Linux)
                # print("客服端的数据", cmd)
                # 2 解析命令。提取相应命令参数
                cmds = res.decode("utf-8").split()
                filename = cmds[1]
    
                #  以读的方式打开文件。读取文件内容发送给客服端
    
                # 第一步:制作固定长度的报头
                heade_dic = {
                    "filename": filename,
                    "md5": "xxxx",
                    "file_size": os.path.getsize(filename)
                }
                heade_json = json.dumps(heade_dic)
                header_bytes = heade_json.encode("utf-8")
                # 第二步:先发送报头的长度
                conn.send(struct.pack("i", len(header_bytes)))
                # 第三步:再发报头
                # print(len(stdout) + len(stderr))
                conn.send(header_bytes)
                # conn.send(str(total_size).encode("utf-8"))
                # 第四步:再发真实的数据
                with open(filename, "rb") as f:
                    for line in f:
                        conn.send(line)
            except ConnectionResetError:
                # 适用window操作系统
                break
        conn.close()
    phone.close()
    View Code
  • 相关阅读:
    python 图片验证码降噪
    python 视频配音、剪辑
    Python实现音乐的剪辑
    OpenCV-Python 视频读取
    OpenCV-Python 人脸眼睛嘴识别
    OpenCV-Python 人脸识别
    numpy
    python学习笔记(3)---cookie & session
    python爬虫学习笔记(2)-----代理模式
    python爬虫学习笔记(1)
  • 原文地址:https://www.cnblogs.com/zqxqx/p/9345457.html
Copyright © 2011-2022 走看看