为什么这个python套接字聊天服务器不能正常工作?

2024-04-29 09:03:28 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我做了一些代码如下。它应该让服务器和客户端通信。。。但它不起作用。你知道吗

有人能解释一下原因吗,或者更好的办法是修复我的代码???你知道吗

服务器。你知道吗

import time
import socket
from threading import Thread

global sS
sS = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sS.bind(('', 2347))
sSconAddresses = []
sSconData = []
print(" Server : Running ... ")
sS.listen(10)

while True:
    try:
        cOn, aDr = sS.accept()
        sSconAddresses.insert(0, str(aDr))
        sSconData.insert(0, str(cOn))
        time.sleep(0.3)
    except:
        time.sleep(0.1)
        pass
def ConHandler():
    for _ in sSconData:
        PacketData = _.recv(700)
        if not PacketData:
            _.close()
        else:
            stringData = PacketData.decode('utf-8')
            print(stringData)
            sS.sendto(PacketData, _)
ConHandlerThread = Thread(target=ConHandler)
ConHandlerThread.daemon = True
ConHandlerThread.start()

客户。你知道吗

import threading, time
import socket, sys
import os

global cS
cS = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cS.connect(('PRIVATE', 2347))
Server = ('PRIVATE', 2347)


while True:
    PacketData = input(" Client> ")
    ByteData = PacketData.encode('utf-8')
    cS.sendto(ByteData, Server)

它没有返回任何错误,所以我不明白为什么它不工作。你知道吗


Tags: 代码import服务器trueservertimesocketcs
1条回答
网友
1楼 · 发布于 2024-04-29 09:03:28

首先,在服务器端代码中,在启动线程之前有一段时间是True,所以它不能工作。你知道吗

然后,如果您通过移动代码成功地启动了线程,那么它的for将看到一个空列表,因此它不会循环,只需在这里退出即可。你知道吗

从你的代码开始,这里有一些有用的东西:

委托人:

import socket


def main():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(('127.0.0.1', 2345))
    while True:
        packetdata = input(" Client> ")
        bytedata = packetdata.encode()
        client_socket.send(bytedata)
        print(client_socket.recv(700).decode())


if __name__ == '__main__':
    main()

服务器:

import socket
from threading import Thread
from queue import Queue


def client_handler(client_socket):
    while True:
        data = client_socket.recv(700)
        print(data)
        client_socket.send("Server {}".format(data.decode()).encode())


def conn_handler(conn_queue):
    while True:
        conn, address = conn_queue.get()
        print("Handler getting a connection from {}".format(address))
        client_thread = Thread(target=client_handler, args=(conn,))
        client_thread.daemon = True
        client_thread.start()


def main():
    print("Server: Running ...")
    conn_queue = Queue()
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('', 2345))
    server_socket.listen(10)


    con_handler_thread = Thread(target=conn_handler, args=(conn_queue,))
    con_handler_thread.daemon = True
    con_handler_thread.start()

    while True:
        conn_queue.put(server_socket.accept())


if __name__ == '__main__':
    main()

请注意,这是次优的,每个客户机启动一个线程是而不是的方法。处理这种情况的最佳方法是将所有内容都保存在一个线程中,并使用类似select的函数来知道该做什么。但是select也有一点限制(比如1024个最大连接,在libc中硬编码),所以方法是使用epoll/kqueue/比poll/select更好的任何东西,并且有一个模块:https://docs.python.org/3/library/select.html

然而,使用select模块仍然是旧的、手工的、体积庞大的表达需求的方式,您应该看看coroutine based API of asyncio,它可以用一种清晰的方式来表达您的意图。你知道吗

asyncio等效项可能如下所示:

import asyncio


async def client():
    reader, writer = await asyncio.open_connection('127.0.0.1', 8888)

    while True:
        message = input("Client> ")
        writer.write(message.encode())
        data = await reader.read(100)
        print('Received: {}'.format(data.decode()))

loop = asyncio.get_event_loop()
loop.run_until_complete(client())

服务器端:

import asyncio


async def handle_client(reader, writer):
    while True:
        data = await reader.read(100)
        if not data:
            return
        message = data.decode()
        addr = writer.get_extra_info('peername')
        print("Received %r from %r" % (message, addr))

        print("Send: %r" % message)
        writer.write(data)
        await writer.drain()


loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_client, '127.0.0.1', 8888)
server = loop.run_until_complete(coro)
print('Serving on {}'.format(server.sockets[0].getsockname()))
loop.run_forever()

相关问题 更多 >