Python中的socket模块

socket模块

我们先来看一个socket编程流程图

在这里插入图片描述

这里的server端就是部署到服务器上的服务端,client端就是对应我们的PC软件浏览器,不过浏览器内部已经帮我们封装了socket

简单的socket通信

  • socket_server.py

    import socket
    
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('0.0.0.0', 8000))
    server.listen()
    sock, addr = server.accept()
    
    # 获取从客户端发送的数据
    # 一次获取1024个字节的数据
    data = sock.recv(1024)
    print(data.decode('utf-8'))
    sock.send(f"hello {data.decode('utf-8')}".encode('utf-8'))
    sock.close()
    
  • socket_client.py

    import socket
    
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect((('127.0.0.1', 8000)))
    client.send("Wilson".encode('utf-8'))
    data = client.recv(1024)
    print(data.decode('utf-8'))
    client.close()
    

首先启动server端(如果先启动client端会因为无法连接server端而导致启动失败),server端会挂起等待client端发送网络请求,server端接收到网络请求后也会向client端发送数据

在这里插入图片描述

注意:数据传输时是二进制,我们打印时需要转换成utf-8

socket实现简单实时聊天和多用户连接

关于实时聊天,我们可以采用While循环

关于多用户连接,我们可以使用多线程技术

  • socket_server.py

    import socket
    import threading
    
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('0.0.0.0', 8000))
    server.listen()
    
    
    def handle_sock(sock, addr):
        data = sock.recv(1024)
        print(data.decode('utf-8'))
        re_data = input()
        sock.send(re_data.encode('utf-8'))
    
    
    while True:
        sock, addr = server.accept()
    
        # 用线程去处理新接受的用户连接
        client_thread = threading.Thread(target=handle_sock, args=(sock, addr))
        client_thread.start()
    
        data = sock.recv(1024)
        print(data.decode('utf-8'))
        re_data = input()
        sock.send(re_data.encode('utf-8'))
    
  • server_client.py

    import socket
    
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect((('127.0.0.1', 8000)))
    
    while True:
        re_data = input()
        client.send(re_data.encode('utf-8'))
        data = client.recv(1024)
        print(data.decode('utf-8'))
    

在这里插入图片描述

socket模拟HTTP请求

import socket
from urllib.parse import urlparse


def get_url(url):
    # 通过socket请求html
    url = urlparse(url=url)
    host = url.netloc
    path = url.path
    if path == "":
        path = "/"

    # 建立socket连接
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect((host, 80))
    client.send(f"GET {path} HTTP/1.1\r\nHost:{host}\r\nConnection:close\r\n\r\n".encode('utf-8'))
    data = b""
    while True:
        d = client.recv(1024)
        if d:
            data += d
        else:
            break
    data = data.decode('utf-8')
    html_data = data.split("\r\n\r\n")[1]
    print(html_data)
    client.close()


if __name__ == "__main__":
    get_url("http://www.baidu.com")

这个案例中通过scoket模拟http请求获得百度的前端页面数据

在这里插入图片描述

报错解决:

OSError: [WinError 10038] 在一个非套接字上尝试了一个操作。

每次循环的时候把socket的客户端给关闭了,所以无法正常连接导致报错

在这里插入图片描述

简单粗暴的解决办法就是client端和server端连接通道不人为关闭,就是删除最后的close代码块

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值