2

私はソケットプログラミングとpythonを学んでいます。コマンドをサーバーに送信するクライアントを作成する必要があります ( list または get )。次に、サーバーはコマンドを検証します。私のクライアント プログラムは "list" または "get" を表示できますが、それ以外を入力してもエラー メッセージが表示されません。
また、一度しか機能しません。サーバーからの応答を受信した後に別のコマンドを入力すると、次のエラーが表示されます。

トレースバック (最新の呼び出しが最後): ファイル "fclient.py"、49 行目、client_socket.send(command) ファイル "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket. py"、170 行目、_dummy raise error(EBADF、'Bad file descriptor') で

私は完全に迷っています。クライアント プログラムでコマンド ライン入力を取得してサーバーに送信し、コマンド ライン パラメータを検証するようにサーバーに依頼する最良の方法は何ですか? 誰かが見て、私を正しい方向に向けることができますか? よろしくお願いいたします。

Client.py

import socket   #for sockets
import sys      #for exit

command = ' '
socksize = 1024

#return a socket descriptor which can be used in other socket related functions
#properties: address family: AF_INET (IP v4)
#properties: type: SOCK_STREAM (connection oriented TCP protocol)

try:
    #create an AF_INET, STREAM socket (TCP)
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:               #error handling
    print 'Failed to create socket. Error code: ' + str(msg[0]) + ', Error message: ' + msg[1]
    sys.exit();

print 'Socket Created'

#Get the IP address of the remote host/url
#connect to IP on a certain 'port' using the connect
#host = 'flip3.engr.oregonstate.edu'
#port = 30021
#host = 'www.google.com'
#port = 80
host = ''       #symbolic name meaning the local host
port = 8888     #arbitrary non-privileged port

try:
    remote_ip = socket.gethostbyname(host)
except socket.gaierror:
    #could not resolve
    print 'Hostname could not be resolved. Existing'
    sys.exit()
print 'IP address of ' + host + ' is ' + remote_ip

#Connect to remote server
client_socket.connect((remote_ip, port))
print 'Socket Connected to ' + host + ' on ip ' + remote_ip


#Send some data to remote server
while True:
    print 'Enter a command: list or get <filename>'
    command = raw_input()
    if command.strip() == 'quit':
        break
    client_socket.send(command)

    data = client_socket.recv(socksize)
    print data

#Close the socket
client_socket.close()

サーバー.py

import socket
import sys
from thread import *

#HOST = 'flip3.engr.oregonstate.edu' #symbolic name meaning all available interfaces
#PORT = 30021
HOST = ''
PORT = 8888

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    server_socket.bind((HOST, PORT))    #bind to a address(and port)
except socket.error, msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

print 'Socket bind complete'

#put the socket in listening mode
server_socket.listen(10)     #maximum 10 connections
print 'TCP Server Waiting for client on port 30021'

#wait to accept a connection - blocking call
client, addr = server_socket.accept()
#display client information
print 'Connected with ' + addr[0] + ':' + str(addr[1])

#keep talking with the client
while 1:
    #Receiving from client
    data = client.recv(1024)

    if (data == 'list' or data == 'get'):
        reply = 'receive: ' + data
        client.send(reply)
        break;
    else:
        reply = 'wrong command'
        client.send(reply)

client.close()
4

2 に答える 2

3

最初の問題は、ループ内でクライアント ソケットを閉じて、最初のコマンドへの応答を受け取った後に閉じることです。代わりにソケットを閉じてループの外に移動し、終了条件を導入してループを終了します。

#Connect to remote server
client_socket.connect((remote_ip, port))

print 'Socket Connected to ' + host + ' on ip ' + remote_ip

#Send some data to remote server
while True:
    print 'Enter a command: list or get <filename>'
    command = raw_input()
    if command.strip() == 'quit':
        break
    client_socket.send(command)

    data = client_socket.recv(socksize)
    print data

# Close the socket
client_socket.close()

サーバー側でも同様のことを行っています。反復ごとにリスニングソケットを再度開いてみます。この部分もループの外に移動します。

#wait to accept a connection - blocking call
client, addr = server_socket.accept()

#display client information
print 'Connected with ' + addr[0] + ':' + str(addr[1])

コマンドの解析が機能しない理由は、次のステートメントが原因です。

if (data == 'list' or 'get'):

あなたがここに書きたかったのは、

if (data == 'list' or data == 'get'):

最初の式は次のように評価されます。

  • ですかdata == 'list'
  • はいの場合、その部分式は評価されTrue、したがってa or b返されるものです。
  • そうでない場合は、文字列である to の 2 番目のオペランドorが選択されます'get'
  • その式の結果は、次のステートメントorによって暗黙的にブール値にキャストされます。if
  • ケース 1:TrueすでにTrue
  • ケース 2: ブール値にキャストされた空でない文字列Trueも同様に評価される

したがって、ifステートメントは常に と評価されTrueます。そのため、コマンドの解析が機能しませんでした。

書く

if (data == 'list' or data == 'get'):

より良い形で、私は使用することをお勧めします

if (data.strip() in ('list'  'get')):

最後に、ソケット コードを でラップして、次のような例外が発生try..finallyした場合でもソケットが常に閉じられるようにする必要があります。KeyboardInterrupt

try:
    #keep talking with the client
    while 1:
        #Receiving from client
        data = client.recv(1024)

        if (data.strip() in ('list'  'get')):
            reply = 'receive: ' + data
            client.send(reply)
        else:
            reply = 'wrong command'
            client.send(reply)
except KeyboardInterrupt:
    print "Exiting gracefully."
finally:
    server_socket.close()

(finally句はすべての状況で実行されます - 処理された例外または未処理の例外が発生したかどうかに関係なく)

于 2013-11-13T18:08:41.693 に答える
0

client_socket1 つの問題は、while ループで閉じることです。その後、client_socket.send()もう動作しません。これを修正するには、少なくとも 2 つの方法があります。

  1. client_socket.connect()while ループにも移動します。
  2. を取り除き、Server.py の while ループの上にclient_socket.close()移動します。server_socket.accept()

または他の方法を含む、より洗練されたオプションがありますがselect()、今のところ、上記の 2 つの項目のいずれかで十分です。

于 2013-11-13T18:05:39.403 に答える