クライアント(Pythonプログラム)がサーバー(cプログラム)から応答を受信しませんか?

N. Dijkhoffz

サーバー側で作業しているUDPソケットアプリケーションがあります。サーバー側をテストするために、「hello world howareyou」というメッセージを送信する簡単なPythonクライアントプログラムを作成しました。サーバーは、メッセージを受信し、大文字に変換して、クライアントに送り返す必要があります。問題はここにあります。デバッグ中に、サーバーがメッセージを受信し、変換を適用し、応答を送り返し、最終的に別のメッセージを待機していることを確認できます。ただし、Pythonクライアントはメッセージを受信して​​いませんが、サーバーからの応答を際限なく待ちます。

私はWebを通じて(オプション)、クライアントが応答を受信するためにサーバーにバインドする必要があることを発見しました。これは、教科書(Linuxプログラミングインターフェイス)で見たものに反します。それにもかかわらず、クライアントをサーバーにバインドしようとしましたが、Pythonプログラムはバインドラインで接続できませんでした(正しく接続したかどうかはわかりません)。Pythonのバージョンは2.7.5です。クライアントプログラムはRedHatで実行され、サーバーはAngstromを備えたターゲットモジュールで実行されます(32ビットプロセッサ用にクロスコンパイルされています)。

クライアントのコードは次のとおりです。

import socket
import os

UDP_IP = "192.168.10.4"
UDP_PORT = 50005

#dir_path = os.path.dirname(os.path.realpath(__file__))

MESSAGE = "hello world how are you"

print "UDP target IP: ", UDP_IP
print "UDP target port: ", UDP_PORT
print "message: ", MESSAGE

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#sock.bind((UDP_IP, UDP_PORT))
print "Sending message..."
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
print "Message sent!"
print "Waiting for response..."
data = sock.recv(1024)

print "Received", repr(data)

そして、これがサーバーのコードです。

void server_side(void)
{
    printf("Server start up.\n");

    struct sockaddr_in svaddr;
    struct sockaddr_in claddr;
    int sfd;
    int j;
    ssize_t numBytes;
    socklen_t len;
    char buf[BUF_SIZE];
    char claddrStr[INET_ADDRSTRLEN];

    //int output = open("test_output.txt", O_WRONLY|O_CREAT, 0664);

    printf("Creating new UDP socket...\n");

    sfd = socket(AF_INET, SOCK_DGRAM, 0);   /* Create Server Socket*/
    if (sfd == -1)
    {
        errExit("socket");
    }

    printf("Socket has been created!\n");

    memset(&svaddr, 0, sizeof(struct sockaddr_in));

    svaddr.sin_family = AF_INET;
    svaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    svaddr.sin_port = htons(PORT_NUM);

    printf("Binding in process...\n");

    if (bind(sfd, (struct sockaddr *) &svaddr, sizeof(struct sockaddr_in)) 
                == -1)
    {
        errExit("bind");
    }

    printf("Binded!\n");

    /* Receive messages, convert to upper case, and return to client.*/

    for(;;)
    {
        len = sizeof(struct sockaddr_in);
        numBytes = recvfrom(sfd, buf, BUF_SIZE, 0,
                (struct sockaddr *) &claddr, &len);
        if (numBytes == -1)
        {
            errExit("recvfrom");
        }
        if (inet_ntop(AF_INET, &claddr.sin_addr, claddrStr,
                INET_ADDRSTRLEN) == NULL)
        {
            printf("Couldn't convert client address to string.\n");
        }
        else
        {
            printf("Server received %ld bytes from (%s, %u).\n", (long)
                numBytes,
                    claddrStr, ntohs(claddr.sin_port));
        }

        claddr.sin_port = htons(PORT_NUM);

        for (j = 0; j< numBytes; j++)
        {
            buf[j] = toupper((unsigned char) buf[j]);
        }

        if (sendto(sfd, buf, numBytes, 0, (struct sockaddr *) &claddr, len)
               != numBytes)
        {
            fatal("sendto");
        }
    }
}

繰り返しますが、問題は、応答を受信せず、クライアント端末にメッセージを出力しないことです。すべて大文字で同じメッセージを受け取るはずです。細かい部分が欠けているような気がします。助けてくれてありがとう!

アーサー・モラエス・ド・ラーゴ

速くて汚い:

Cコードから次の行を削除します。

claddr.sin_port = htons(PORT_NUM);

なぜ:

pythonスクリプトでメッセージを送信すると、オペレーティングシステムは、指定した宛先IPアドレスとポート、送信元IPフィールドで使用しているマシンのIPアドレス、最後に割り当てられた送信元ポートをUDPパケットに入力します。 OSによって「ランダムに」。これは宛先ポートと同じポートではないことに注意してください。たとえそうであったとしても、どのプログラムが送信元メッセージを受信するかをどうやって知ることができますか?(どちらも同じポートからメッセージを聞くことになります)幸いなことに、これはそうではありません可能。

これで、Cコードがこのパケットを受信すると、誰がメッセージを送信したかがわかり、recvfromで埋められたsockaddr構造体を介してこの情報にアクセスできます。情報を送り返したい場合は、クライアントから見た送信元ポートと同じ宛先ポート(サーバーから見て)でパケットを送信する必要があります。これも、リッスンしているポートとは異なります。サーバ。を実行するcladdr.sin_port = htons(PORT_NUM)と、クライアントの送信元ポートを含むフィールドをサーバーポートで上書きするように設定します。このパケットを送信しようとすると、次の2つのことが発生する可能性があります。

  • クライアントが同じコンピューターから実行された場合、宛先IPと送信元IPは同じになり、宛先ポートをサーバーがリッスンしているポートに設定しただけなので、メッセージループが発生します。
  • 別のコンピューターで実行されている場合、パケットはクライアントコンピューターによって受信されますが、そのポートでメッセージを待機しているプログラムはおそらくないため、破棄されます。

中途半端な例え:あなたは友人から手紙を受け取りますが、彼に手紙を書くとき、あなたは彼の家の番号をあなたの家の番号に変えます...あまり意味がありません。唯一の違いは、あなたのこの友人はたくさん動くことであり、各文字は異なる番号を持っているかもしれませんが、それは重要ではありません。

理論的には、データを受信する場合はバインドする必要があります。この場合、バインドはそのポートをリッスンすることと同じです。この回答は、この場合に必要ではなかった理由を明確にしていますhttps//stackoverflow.com/a/14243544/6253527

Linuxを使用している場合は、OSがUDPソケットに割り当てたポートを使用して確認できます。 sudo ss -antup | grep python

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

nettyクライアントはサーバーから1つの応答しか受信できません

分類Dev

UWPアプリはローカルホスト上の.NETデスクトップアプリからUDPデータグラムを受信しません

分類Dev

TCPクライアントプログラムがサーバーに接続しません

分類Dev

ローカルマシン上のJavaのUDPクライアントサーバー、クライアントプログラムが応答しない

分類Dev

Javaソケットがプリントライターからの応答を受信していません

分類Dev

Typescriptは、サーバーからカスタムタイプ変数への応答を受信したときにエラーを確認しません

分類Dev

バックグラウンドのアプリは、チタンのアンドロイド用のpubnubからメッセージを受信しません

分類Dev

BroadCastReceiverを備えたAlarmManager:2つのアラームをプログラムしましたが、1つしか受信しませんでした

分類Dev

実サーバーにアップロードし、ログイン時に見つからないblowfishクラスを受信します

分類Dev

サーバーはcwinsockプログラミングでクライアントメッセージを受信できません

分類Dev

ファイル名を使用して「プログラムで」サーバー上のクライアントからファイルをアップロードするか、UploadFileControlに「プログラムで」ファイル名を割り当てます

分類Dev

Azureコンテナ-プライベートレジストリにログインできません「Dockerレジストリからエラー応答を受信しました」

分類Dev

C ++サーバーがクライアント/ Winsockからデータを受信できません

分類Dev

socket.ioクライアントがサーバーからio.emitを受信していません(redisアダプターを使用)

分類Dev

Steam およびその他のいくつかのプログラムからキーストロークを受信できません

分類Dev

プログラムでボタンアウトレットからUIButtontitleLabelプロパティをオーバーライドできません

分類Dev

PythonサーバーとJavaクライアント:サーバーはメッセージを受信しますが、クライアントは応答を受信しません

分類Dev

Nginxプロキシ-アップストリームでUDPデータグラムをバインドしません(不正なUDPチェックサム)

分類Dev

クライアント/サーバープログラムでデッドロックを見つけることができません

分類Dev

プログラムでファイルからWebページを開き、リンクをクリックして応答C#を処理します

分類Dev

GLSL-プログラムリンクエラー:レイアウトロケーション要求からスロット0を使用できません

分類Dev

Golang TCPクライアントがサーバーからデータを受信せず、conn.Read()でハング/ブロックする

分類Dev

ScrapyrtがScrapyクローラーから応答を受信していません

分類Dev

サーバークライアントのファイル転送プログラムでエラーが発生しましたか?

分類Dev

クライアントがhttp応答を受信することは可能ですが、サーバーはそれを受信したかどうか確信がありませんか?

分類Dev

ソケットプログラミングでサーバーからクライアントにintを送信できません

分類Dev

複数のクライアントからサーバーへのJava通信プログラム

分類Dev

クライアントがshutdown(sockfd、SHUT_RD)を呼び出した後、クライアントプログラムのrecv()がクライアントに送信されたメッセージを受信できるのはなぜですか?

分類Dev

hackerRankでサンプルテスト用のプログラムを書いていますが、ループが機能していないか、1つの出力しか受信していないと言わなければなりません。

Related 関連記事

  1. 1

    nettyクライアントはサーバーから1つの応答しか受信できません

  2. 2

    UWPアプリはローカルホスト上の.NETデスクトップアプリからUDPデータグラムを受信しません

  3. 3

    TCPクライアントプログラムがサーバーに接続しません

  4. 4

    ローカルマシン上のJavaのUDPクライアントサーバー、クライアントプログラムが応答しない

  5. 5

    Javaソケットがプリントライターからの応答を受信していません

  6. 6

    Typescriptは、サーバーからカスタムタイプ変数への応答を受信したときにエラーを確認しません

  7. 7

    バックグラウンドのアプリは、チタンのアンドロイド用のpubnubからメッセージを受信しません

  8. 8

    BroadCastReceiverを備えたAlarmManager:2つのアラームをプログラムしましたが、1つしか受信しませんでした

  9. 9

    実サーバーにアップロードし、ログイン時に見つからないblowfishクラスを受信します

  10. 10

    サーバーはcwinsockプログラミングでクライアントメッセージを受信できません

  11. 11

    ファイル名を使用して「プログラムで」サーバー上のクライアントからファイルをアップロードするか、UploadFileControlに「プログラムで」ファイル名を割り当てます

  12. 12

    Azureコンテナ-プライベートレジストリにログインできません「Dockerレジストリからエラー応答を受信しました」

  13. 13

    C ++サーバーがクライアント/ Winsockからデータを受信できません

  14. 14

    socket.ioクライアントがサーバーからio.emitを受信していません(redisアダプターを使用)

  15. 15

    Steam およびその他のいくつかのプログラムからキーストロークを受信できません

  16. 16

    プログラムでボタンアウトレットからUIButtontitleLabelプロパティをオーバーライドできません

  17. 17

    PythonサーバーとJavaクライアント:サーバーはメッセージを受信しますが、クライアントは応答を受信しません

  18. 18

    Nginxプロキシ-アップストリームでUDPデータグラムをバインドしません(不正なUDPチェックサム)

  19. 19

    クライアント/サーバープログラムでデッドロックを見つけることができません

  20. 20

    プログラムでファイルからWebページを開き、リンクをクリックして応答C#を処理します

  21. 21

    GLSL-プログラムリンクエラー:レイアウトロケーション要求からスロット0を使用できません

  22. 22

    Golang TCPクライアントがサーバーからデータを受信せず、conn.Read()でハング/ブロックする

  23. 23

    ScrapyrtがScrapyクローラーから応答を受信していません

  24. 24

    サーバークライアントのファイル転送プログラムでエラーが発生しましたか?

  25. 25

    クライアントがhttp応答を受信することは可能ですが、サーバーはそれを受信したかどうか確信がありませんか?

  26. 26

    ソケットプログラミングでサーバーからクライアントにintを送信できません

  27. 27

    複数のクライアントからサーバーへのJava通信プログラム

  28. 28

    クライアントがshutdown(sockfd、SHUT_RD)を呼び出した後、クライアントプログラムのrecv()がクライアントに送信されたメッセージを受信できるのはなぜですか?

  29. 29

    hackerRankでサンプルテスト用のプログラムを書いていますが、ループが機能していないか、1つの出力しか受信していないと言わなければなりません。

ホットタグ

アーカイブ