python的socket库

python学习socket库(套接字)

TCP:

使用默认的方式:

服务端:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 6969))
sock.listen(5)

while True:
    conn, addr = sock.accept()
    with conn:
        print('Connected By:', addr)
        while True:
            try:
                recv_data = conn.recv(1024)
                if not recv_data:
                    break
                print('accept mag:', recv_data.decode())
                conn.sendall(recv_data)
            except ConnectionResetError as e:
                print('close using connection!')
                break
    conn.close()
sock.close()

服务端:

import socket


HOST = '192.168.41.192'
PORT = 6969

sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_client.connect((HOST, PORT))
while True:
    msg = input('>>>>:').strip()
    sock_client.sendall(msg.encode())
    data = sock_client.recv(1024)
    print('client accept msg:', data.decode())

默认的socket是阻塞的方式

使用非阻塞情况下:

import socket

# 同步非阻塞

HOST = ''
PORT = 50007

sock = socket.socket()
sock.setblocking(False)   # 设置非阻塞 默认为阻塞TRUE
sock.bind((HOST, PORT))
sock.listen(5)

while True:
    try:
        conn, addr = sock.accept()  # 没有连接会引发BlockingIOError
        with conn:
            print('Connected by:', addr)
    except BlockingIOError:
        pass

使用非阻塞实现并发:

import socket

#  使用同步非阻塞实现服务器并发(缺点:任意一个客服端关闭,服务端会随着客服端关闭)

HOST = ''
PORT = 50007
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(False)
sock.bind((HOST, PORT))
sock.listen(5)
client_list = []

while True:
    # 接受数据
    try:
        conn, addr = sock.accept()
        conn.setblocking(False)   # 设置这个对等数列链接为非阻塞
        client_list.append((conn, addr))
        print('Connected by: {}'.format(addr))
    except BlockingIOError:
        pass

    # 处理请求
    for client, addr in client_list:
        try:
            recv_data = client.recv(1024)
            if recv_data:
                print('接受来自:{}>>>{}'.format(addr, recv_data.decode()))
                client.sendall(recv_data)
            else:
                # 关闭链接
                client_list.remove((client, addr))   # 从列表中删除
                client.close()
                print('断开链接:{}'.format(addr))
        except BlockingIOError:
            pass

为了提高效率,使用epoll实现并发服务器:

import socket
import selectors



HOST = '192.168.41.192'
PORT = 50007
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)

def recv(soc):
    try:
        data = soc.recv(1024)
        if data:
            print("accept data:", data.decode())
            soc.send(data)
        else:
            # 删除注册
            epoll_selector.unregister(soc)
            soc.close()
    except ConnectionResetError as e:
        print('close connection.')
        epoll_selector.unregister(soc)
        soc.close()


def accept(soc):
    # 接受请求
    conn, addr = soc.accept()
    print("Connected by:", addr)
    # 把对等链接注册到epoll监视器
    epoll_selector.register(
        conn,
        selectors.EVENT_READ,
        recv
    )


# 创建一个epoll监视器
# epoll_selector = selectors.DefaultSelector()   # 根据操作系统自己选择(这里是window)
epoll_selector = selectors.EpollSelector()

# 注册
epoll_selector.register(
    sock,
    selectors.EVENT_READ,
    accept
)

# 循环监听
while True:
    # events 是一个列表
    events = epoll_selector.select()
    # events 就是所有被触发 的事件
    for key, mark in events:
        sock = key.fileobj
        callback = key.data
        # 执行回调函数
        callback(sock)

实现Linux定时执行脚本:

shell脚本代码:

#! /bin/bash

pid=$(ps -ef | grep "new_server.py" | grep -w "python3")
echo "pid=$pid" >> /home/app/a.log
if [ "x$pid" == "x" ]; then
        python3 /home/app/new_server.py &
fi

需要在crontab -e打开文件

* * * * *  sh /home/app/test.sh >/dev/null 2>&1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值