2

私はbsdソケットを使用してLinuxで簡単なチャットプログラムを実装しようとしています。現在、クライアントからサーバーに1つのメッセージを送受信しようとしています。コードを実行するたびに、recvは-1を返し、errnoコードは22です。

サーバーコード-

struct sockaddr name;
char buf[80];

int main(int agrc, char** argv) {

    int sock, new_sd;   //sock is this socket, new_sd is connection socket
    int adrlen, cnt;

    name.sa_family = AF_UNIX;
    strcpy(name.sa_data, "/tmp/servsock");
    adrlen = strlen(name.sa_data) + sizeof(name.sa_family);

    sock = socket(AF_UNIX, SOCK_STREAM, 0);

    if (sock < 0) {
        cout<<"\nserver socket failure "<<errno;
        cout<<"\nServer: ";
        exit(1);
    }

    unlink("/tmp/servsock");
    if(bind (sock, &name, adrlen) < 0)
        cout<<"\nBind failure "<<errno;

    if(listen(sock, 5) < 0)
        cout<<"\nlisten error "<<errno;

    while(1) {
        if( new_sd = accept(sock, &name, (socklen_t*)&adrlen) < 0) {
            cout<<"\nserver accept failure "<<errno;
            exit(1);
        }

        char* buf = new char[14];

        if(recv(sock, buf, 14, 0) < 0) {
            cout<<"\nError receiving data "<<errno;
            exit(1);
        }
    }   //end while
    return 0;
}

クライアントコード-

struct sockaddr name;

int main(int agrc, char** argv) {

    int sock, new_sd, adrlen, cnt;
    sock = socket(AF_UNIX, SOCK_STREAM, 0);

    if (sock < 0) {
        cout<<"\nserver socket failure "<<errno;
        cout<<"\nServer: ";
        exit(1);
    }

    //stuff for server socket
    name.sa_family = AF_UNIX;
    strcpy(name.sa_data, "/tmp/servsock");
    adrlen = strlen(name.sa_data) + sizeof(name.sa_family);

    if(connect(sock, &name, adrlen) < 0) {
        cout<<"\nclient connection failure "<<errno;
        exit(1);
    }

    cout<<"\nSuccessful connection from client 1";

    std::string buf = "\nClient 1 Here";

    if(send(sock, buf.c_str(), strlen(buf.c_str()), 0) < 0) {
        cout<<"\nError sending data from client 1 "<<errno;
        exit(1);
    }
    cout<<"\nExiting normally";
    return 0;
}

サーバー側でエラーが発生しても、クライアント側ではエラーメッセージが表示されません。正常に終了します。

-http ://www.workers.com.br/manuais/53/html/tcp53/mu/mu-7.htmによると 、errno22エラーメッセージは単に「無効な引数」を意味します。しかし、それをどのように正確に解釈するかはわかりません...引数が無効だった場合、なぜそれがコンパイルされるのでしょうか?

私がここで間違っていることを誰かが指摘できれば、私はとても感謝しています。そして、あなたが指摘したいと思う他の小さなメモは歓迎されます。助けてくれてありがとう。

4

3 に答える 3

5

コード内の他のすべての問題は別として、間違ったファイル記述子を読み取ろうとしています。これは、サーバーソケットであり、新しい接続しかできない、new_sdではなく、である必要があります。sockaccept()

編集0:

ビッグブーブー:

if( new_sd = accept(sock, &name, (socklen_t*)&adrlen) < 0) { ...

これは次と同等です。

if( new_sd = (accept(sock, &name, (socklen_t*)&adrlen) < 0)) {

したがってnew_sd、完全に間違った値を取得します。一般的な知恵は、割り当てを条件文に入れないことです。少なくとも、高い警告レベルでコンパイルすることを検討してください-Wall -pedantic

于 2011-07-13T22:18:01.620 に答える
2

コードで間違っているように見えることの1つは、から実行する必要があるときに実行recvしていることです。しかし、なぜそれが得られるのかわかりません。sockrecvnew_fdEINVAL

EINVALエラーは(通常)コンパイル時に検出できません。ファイル記述子はプレーンintです。コンパイラは、実行時に有効なファイル記述子がどれであるか、または使用しているソケットに対してint特定の組み合わせが有効かどうかを知ることができません。)flags

于 2011-07-13T22:18:25.727 に答える
0

(サーバーでの)「recv()」呼び出しでは、「flags」パラメーターを0にすることはできません。

recv(sock, buf, 14, 0)

次のようなものを試してください:

recv(sock, buf, 14, MSG_WAITALL)

'flags'パラメータのオプションの全リストについては、'man'ページを参照してください。ここでは、メッセージの受信方法を慎重に検討する必要があります。

クライアントがエラーメッセージ(INVALID ARG)を受け取らない理由は、クライアントが受信を行わないためです...サーバーのみが受信を行っています。

于 2011-08-26T23:43:31.677 に答える