7

私は Python プログラミングが初めてで、サーバーとクライアントを作成しようとしています。「exit」と入力してサーバーからサーバーを閉じることができるように、キーボードから何かを入力できるようにしたいのです。さまざまなサイトからサンプル コードを取得して、ソケット プログラミングとこのコードのどこにいるのかを調べました。

ただし、コードを実行するたびに、次のエラー メッセージが表示されます。

The host name of this machine is 127.0.0.1
The IP address of the host is 127.0.0.1
Server now awaiting client connection on port 2836
im right before the select
Traceback (most recent call last):
  File "/root/Server_2.py", line 42, in <module>
    inputready, outputready, exceptready = select.select(input, [], [])
TypeError: argument must be an int, or have a fileno() method.
>>> 

Windowsはソケットのみを受け入れるため、これを(Windowsで)渡すにはsys.stdinを削除する必要があることを読んでいました。このコードを Linux で記述しようとしています。私はそれを機能させるためにあらゆる種類のことを試しましたが、試すリソースとアイデアがすべて不足しています。以下はサーバーコードです。

import socket                       #import socket module
import select
import sys

host = "127.0.0.1"
print ("The host name of this machine is " + host)
hostIP = socket.gethostbyname(host)    # get host IP address
print ("The IP address of the host is %s" % (hostIP)) 
port = 2836                        # Reserve the port for the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((hostIP, port))                # This server to a port

s.listen(4)                         # Now wait for client connection

print("Server now awaiting client connection on port %s" % (port))

#WINDOWS ONLY ACCEPTS SOCKETS FOR SELECT(), no standard in
input = [s, sys.stdin]


running = 1

while running:


    print("im right before the select")
    # when there's something in input, then we move forward
    # ignore what's in output and except because there's nothing
    # when it comes to sockets
    inputready, outputready, exceptready = select.select(input, [], [])

    print("i'm here na")
    # check who made a response
    for x in inputready:

        if x == s:
            print(s)
            #handle the server socket
            client, address = s.accept()
            print("connection comming in")
            input.append(client)

        elif x == sys.stdin:
            # handle standard input
            stuff = sys.stdin.readline()
            if stuff == "exit":
                running = 0
            else:
                print("you typed %s" % (stuff))


        else:
            #handle all other sockets
            data = x.recv(1024)
            print("i received " + data)
            if data:
                if data == "exit":
                    x.close()
                    input.remove(x)
                    running = 0
                else:
                    x.send(data)
                    print("I am sending %s" % (data))
            else:
                x.close()
                input.remove(x)


s.close()

どんな助けやアイデアも大歓迎です。ありがとう!!

4

1 に答える 1

2

7年前にあなたがこれを尋ねたことは知っていますが、同様の質問があったので、私はあなたに答えると思います. 私はまだ同じ機能を持つプログラムの作業とバグ修正を行っていますが、私が知っていることの 1 つは、select.select()必要な引数であるリストはファイル記述子 (int) である必要があるということです。

したがって、このブロックがある場合

input = [s, sys.stdin]


running = 1

while running:


    print("im right before the select")
    # when there's something in input, then we move forward
    # ignore what's in output and except because there's nothing
    # when it comes to sockets
    inputready, outputready, exceptready = select.select(input, [], [])

私が最初に言うことは、読み取りリストを変更しないことinputです。input() 関数と衝突する可能性があり、紛らわしいバグが発生する可能性があります。その後、値をファイル記述子にする必要があります。そのため、最初の行は

inputSockets = [s.fileno(), sys.stdin.fileno()]

次に、どのソケットの準備ができているかを確認するときは、次のようにします

for x in inputready:
    if x == s.fileno():
        # Read from your s socket
    elif x == sys.stdin().fileno():
        # Read from stdin
    else:
        '''
        Here you would want to read from any other sockets you have.
        The only problem is your inputSockets array has ints, not socket
        objects. What I did was store an array of actual socket objects
        alongside the array of file descriptors. Then I looped through the
        list of sockets and found which socket's .fileno() matched x. You could
        probably be clever and use a dict() with the filenos as key and socket as
        value
        '''
于 2020-12-04T15:53:06.453 に答える