首页 > 解决方案 > 如何允许客户端连接到 python 服务器?

问题描述

当我运行服务器,然后是客户端时,我会自动收到这些消息:

**服务器:** 回溯(最近一次调用最后):文件“C:\Users\Ryan\Desktop\testproj-server.py”,第 142 行,在 handleConnectedSocket() 文件“C:\Users\Ryan\Desktop\ testproj-server.py",第 58 行,在 handleConnectedSocket rcvdStr = rcvdStr + fd.recv(1024) TypeError: can only concatenate str (not "bytes") to str

**客户端:**错误:无法连接到聊天服务器 [WinError 10056] 已在已连接的套接字上发出连接请求正在退出...再见!*

这是我的代码:

服务器代码:

import socket
import select


def runSelect():
    selectUnsuccessful = True

    while selectUnsuccessful:
        try:
            readyRecvList, readySendList, readyErrList = select.select(recvList, sendList, [])
            selectUnsuccessful = False
        except select.error:
            for fd in recvList:
                try:
                    tempRecvList, tempSendList, tempErrList = select.select([fd], [], [], 0)
                except select.error:
                    if fd == serverSocket:
                        fd.close()
                        exit(1)
                    else:
                        if fd in recvList:
                            recvList.remove(fd)
                            fd.close()

    return readyRecvList, readySendList


def handleListeningSocket():
    try:
        newConnectionSocket, addr = serverSocket.accept()
    except socket.error as err:
        print("\nERROR: Something went wrong in the accept() function call:", err)
        exit(1)

    try:
        recvList.append(newConnectionSocket)
        sendList.append(newConnectionSocket)
        print("INFO: Connecting socket created between %s and %s" %
              (newConnectionSocket.getsockname(), newConnectionSocket.getpeername()))
        print("* Client %s is ready to chat *" % (str(newConnectionSocket.getpeername())))

    except (socket.error, socket.gaierror) as err:

        print("\nERROR: Something went wrong with the new connection socket:", err)
        if newConnectionSocket in recvList:
            recvList.remove(newConnectionSocket)
            sendList.remove(newConnectionSocket)
            newConnectionSocket.close()


def handleConnectedSocket():
    try:

        recvIsComplete = False
        rcvdStr = ""

        while not recvIsComplete:
            rcvdStr = rcvdStr + fd.recv(1024)

            if fd not in sendList:
                sendList.append(fd)
                # ~ is the delimiter used to indicate message start and finish
                if rcvdStr.strip('~') != "":
                    if (rcvdStr[0] == "~") and (rcvdStr[-1] == "~"):
                        recvIsComplete = True
                        clientMessage = rcvdStr.strip('~')
                    else:  # if empty string, connection has been terminated
                        if fd in recvList:
                            recvList.remove(fd)

            if fd in sendList:
                sendList.remove(fd)
                del clientMessages[fd]  # Delete connection information
                fd.close()

            if clientMessage == "quit()":
                print ("\n* Client %s has left the chat room *\n" % (str(fd.getpeername())))

            if fd in recvList:
                recvList.remove(fd)
                fd.close()

                if fd in sendList:
                    sendList.remove(fd)
                    fd.close()

            else:
                print("\n%s: %s" % (fd.getpeername(), clientMessage))
                # add message to dictionary, pending transmission
                clientMessages[fd] = str(clientMessage)

    except socket.error as err:
        print("\nERROR: Connection to the client has abruptly ended:", err)
        if fd in recvList:
            recvList.remove(fd)

        if fd in sendList:
            sendList.remove(fd)

        fd.close()
        print("* I am ready to chat with a new client! *\n")


"""
main - Runs the Full Duplex Chat server
"""

# Global Variables
serverHost = 'localhost'
serverPort = 22222
recvList = []
sendList = []
clientMessages = {}


try:

    serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serverSocket.setblocking(0)
    serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    serverSocket.bind((serverHost, serverPort))
    serverSocket.listen(3)

    print ("INFO: I am listening at %s" % (str(serverSocket.getsockname())))
    print ("* I am ready to chat with a new client! *\n")

except (socket.error, socket.gaierror) as err:
    print ("\nERROR: Something went wrong in creating the listening socket:", err)
    exit(1)

recvList = [serverSocket]

try:
    while True:
        serverSocket.setblocking(False)
        readyForRecv, readyForSend = runSelect()

        for fd in readyForRecv:
            if fd == serverSocket:
                handleListeningSocket()
            else:
                handleConnectedSocket()

        for fd in readyForSend:
            try:
                if fd in clientMessages.keys():  # See if connection information exists
                    broadcast = str(clientMessages[fd])  # Add message to broadcast variable

                    if broadcast:  # See if a message is actually there
                        for client in readyForSend:  # Broadcast message to every connected client
                            if broadcast != "":
                                print ("* Broadcasting message \"%s\" to %s *" % (str(broadcast), client.getpeername()))
                                client.send(str(fd.getpeername()) + ": " + str(broadcast))

                                clientMessages[fd] = ""  # Empty pending messages
#except:
    # print "\nERROR: Something awful happened while broadcasting messages"
    #break

            except socket.error as err:
                print ("\nERROR: Something awful happened with a connected socket:", err)

                if fd in recvList:
                    recvList.remove(fd)

                if fd in sendList:
                    sendList.remove(fd)

                fd.close()

except KeyboardInterrupt:
    for fd in recvList:
        fd.close()

    for fd in sendList:
        fd.close()

    print ("\nINFO: KeyboardInterrupt")
    print ("* Closing all sockets and exiting... Goodbye! *")
    exit(0)

客户代码:

import socket
import select
import sys


def main():

    serverHost = 'localhost'
    serverPort = 22222

    try:
        clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    except socket.error as err:
        print("ERROR: Cannot create client side socket:", err)
        exit(1)

    while True:
        try:
            clientSocket.connect((serverHost, serverPort))
        except socket.error as err:
            print("ERROR: Cannot connect to chat server", err)
            print("* Exiting... Goodbye! *")
            exit(1)
        except:
            print("ERROR: Something awful happened!")
            exit(1)
            break

    recvList = [clientSocket, sys.stdin]

    print("* You are now connected to chat server %s as %s *" %
          (clientSocket.getpeername(), clientSocket.getsockname()))

    try:
        while True:
            readyRecvList, readySendList, readyErrList = select.select(recvList, [], [])

            for fd in readyRecvList:
                if fd == sys.stdin:
                    message = sys.stdin.readline().rstrip()
                    clientSocket.sendall("~" + str(message) + "~")

                    if (message == "quit()"):
                        print("* Exiting chat room! *")
                        clientSocket.close()
                        exit(0)
                        break

                    elif fd == clientSocket:
                        clientSocket.settimeout(3)
                        try:
                            message = clientSocket.recv(2048)
                        except socket.timeout as err:
                            print("ERROR: The recv() function timed out after 3 seconds! Try again.")
                        except:
                            print("ERROR: Something awful happened!")
                    else:
                        if message == "":
                            break
                else:
                    print("%s\n" % (message))
                    clientSocket.settimeout(None)
                    break

    except select.error as err:
        for fd in recvList:
            try:
                tempRecvList, tempSendList, tempErrList = select.select([fd], [], [], 0)
            except select.error:
                if fd == clientSocket:
                    fd.close()
                    exit(1)
                else:
                    if fd in recvList:
                        recvList.remove(fd)
                        fd.close()

    except socket.error as err:
        print("ERROR: Cannot connect to chat server", err)
        print("* Exiting... Goodbye! *")
        exit(1)

        if fd in recvList:
            fd.close()

    except KeyboardInterrupt:
        print("\nINFO: KeyboardInterrupt")
        print("* Closing all sockets and exiting chat server... Goodbye! *")
        clientSocket.close()
        exit(0)


if __name__ == '__main__':
    main()

标签: pythonserver

解决方案


您没有解码收到的字节

rcvdStr = rcvdStr + fd.recv(1024).decode()

我还没有完全检查,所以告诉我这是否有帮助

编辑:

  1. 好的,所以对于初学者来说,删除客户端第 17 行中的 while 语句,一旦客户端连接到服务器,您就无法再次连接(确保删除新第 26 行中的中断)
  2. 新的第 34 行是 causinf 错误 ( readyRecvList, readySendList, readyErrList = select.select(recvList, [], []))
Traceback (most recent call last):
  File "C:\Users\User\Desktop\Client.py", line 93, in <module>
    main()
  File "C:\Users\User\Desktop\Client.py", line 34, in main
    readyRecvList, readySendList, readyErrList = select.select(recvList, [], [])
io.UnsupportedOperation: fileno

推荐阅读