4

Python では、ローカル ホストとポートで UDP データを送信し、同じプログラム内で同時にローカル ホストの別のポートをリッスンすることはできますか? エラー 48'address already in use' が発生し続け、Python の再利用アドレスを使用しようとしましたが、とにかくこのアプリケーションでは機能しないと確信しています。

背景: 私はソフトウェア開発について何も知りません。ましてや Python については何も知りません。これは誰かが仕事で頼んだものです。

助けていただければ幸いです。

from threading import Thread
import time
import socket


HOST = 'localhost'
PORT = 5455
PORT1 = 5457
data1 = "1"

s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT1))


a = 0
def myfunction(string, *args):
    while 1:
        cmd = int( raw_input("send message: ") )
        if (cmd == 1):
            s.sendto(data1, (HOST,PORT))
            time.sleep(1)

def myfunction2(string, *args):
    while 1:
        print s.recv(30)
        time.sleep(.5)

if __name__=='__main__':

    try:
        Thread(target=myfunction, args=(a, 1)).start()
        Thread(target=myfunction2, args=(a, 1)).start()
    except Exception, errtxt:
        print errtxt
4

2 に答える 2

5

はい、そうです。どの言語でも。同じポートを 2 回リッスンしている可能性があります。TCP および UDP エンドポイントは、IP アドレスとポートによって特徴付けられます。「使用中のアドレス」は、完全一致、同じアドレス同じポートの場合にのみ表示されます。

また、リスニング ポートがまだ で使用されていないことを確認しnetstatます。

更新(l4mpi に感謝): スーパーユーザー権限を持たずに 1024 未満のポートを使用しようとすると、「アクセスが拒否されました」というメッセージが表示されます。

アップデート

コードを少し変更しました。あなたが抱えていた問題の1つは、ソケットの送受信に関する混乱でした。これは「クライアント」機能であり、「サーバー」機能でした。

「1」の代わりにメッセージ本文を照会する自由を取りましたが、必要に応じて元に戻すのは簡単です。

from threading import Thread
import time
import socket

CONN = ('localhost', 5455)

def fn_client(string, *args):
    cs = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    cs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    while 1:
        cmd = int( raw_input("command (1 to send): ") )
        if (cmd == 1):
            data = raw_input("message to send: ")
            cs.sendto(data, CONN)
            time.sleep(1)

def fn_server(string, *args):
    ss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    ss.bind(CONN)
    while 1:
        print "Server received '%s'" % (ss.recv(30))
        time.sleep(.5)

if __name__=='__main__':

    a = 0
    try:
        Thread(target=fn_client, args=(a, 1)).start()
        Thread(target=fn_server, args=(a, 1)).start()
    except Exception, errtxt:
        print errtxt
于 2012-09-20T18:03:18.103 に答える
1

あなたのコードは、それが生成されない限り、私のために機能しAddress already in useます。

しかし、スレッドコードはあまりクリーンでKeyboardInterruptはなく、スレッドで処理されません。これはマルチスレッドの一般的な問題です。これを軽減する方法の例については、この回答またはこのレシピを参照してください。

これは、を使用してプログラムを正常に終了できないことを意味しますCTRL-Ckill [pid]代わりに、おそらく、のようなものを使用することに頼らなければならなかったでしょう-9。私の推測では、を引き起こしたプログラムの以前の実行から残った接続を取得したと思いますAddress already in use。のようなものを使用netstat -anp | grep 5457して、そのポートにまだ接続があるかどうかを判断します。

糸脱毛の良い入門書については、DougHellmanの記事も参照してください。

于 2012-09-20T19:38:07.083 に答える