2017-09-14 29 views
-1

所以我做了一些代码如下。它假设让服务器和客户端进行通信......但它不起作用。为什么这个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) 

它不会返回任何错误,所以我很困惑它为什么不起作用。

回答

0

首先,在您的服务器端代码中,在启动线程之前您有一段时间的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也有点太有限(例如最多1024个连接,在libc中硬编码),所以要走的路是使用epoll/kqueue /比轮询/ select更好,并且这里有一个模块:https://docs.python.org/3/library/select.html

然而,使用选择模块仍然是陈旧的,手工的,立体的方式来表达你的需求,你应该看看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() 
+0

感谢您的解释。 – MAXBD

相关问题