0

クライアントサーバーアプリケーションがあり、tcpソケットを使用しています。クライアント側からのsend()リクエストで、常にバスエラーが発生し、プログラムが終了します。今、私は少しウィキペディアを検索しました、そして記事はバスエラーを(存在しない物理アドレス、整列されていないメモリアクセス、そして切り捨てられたマップされたファイルへのアクセス)に帰します。私が送信している構造は、3つのintとenumインスタンスだけなので、配置が問題になるとは思いません。関連するコードスニペットは次のとおりです。

typedef struct _commsg
{
    RequestType requestType;
    int client_pid;
    int request_id;
    int sector;
}ComMsg; 

メインで:

/* Create a reliable, stream socket using TCP */
if ((sock_id = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    DieWithError("socket() failed\n");

/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
echoServAddr.sin_family      = AF_INET;             /* Internet address family */
echoServAddr.sin_addr.s_addr = inet_addr(loopback_addr);   /* Server IP address */
echoServAddr.sin_port        = htons(SERVER_PORT); /* Server port */

/* Establish the connection to the echo server */
if (connect(sock_id, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
    DieWithError("connect() failed");


if (send(sock_id, (void *)&_commsg, sizeof(ComMsg), 0) != sizeof(ComMsg))
    DieWithError("send() sent a different number of bytes than expected");

そしてサーバー側では:

recv(clntSocket_fd, &_commsg, sizeof(ComMsg), 0);

前もって感謝します。

4

3 に答える 3

1

完全な警告をオンにして (たとえば、gcc、-Werror を使用して) アプリケーションをコンパイルしていますか? あなたがすべき。バス エラーは、ほぼ確実に、不正なポインターにアクセスしている、関数に渡すパラメーターの API に違反しているなどを意味します。完全な警告をオンにしてコンパイルを試み、表示されるすべてのエラーをきれいに修正し、問題が解決するかどうかを確認します。 .

ちなみに、TCP ソケットでは send(2) や recv(2) よりも read(2) や write(2) の方がよく使われます。

于 2012-02-24T22:25:20.557 に答える
0

send(2)のマニュアルページに記載されているように、「send()とwrite(2)の唯一の違いは、フラグの存在です。フラグ引数がゼロの場合、send()はwrite(2)と同等です」

スティーブンスが彼のUnixネットワークプログラミングブックで述べたように。「ストリームソケット(TCPソケットなど)は、通常のファイルI / Oとは異なる読み取りおよび書き込み機能の動作を示します。ストリームソケットでの読み取りまたは書き込みは、要求されたよりも少ないバイトを入力または出力する場合があります。」

したがって、代わりに次の方法でエラーをテストすることをお勧めします。

  if (send(sock_id, (void *)&_commsg, sizeof(ComMsg), 0) < 0)

送信されたバイトのテストは行いません。実際に問題がないときに、アプリケーションを閉じている可能性があります。

ネットワークを介して構造を送信することは、通常、自分とは異なる他のシステムに接続するときにエンディアンに関連する問題に陥る可能性があるため、お勧めできません。推奨される方法は、バイト文字列を使用することです。

于 2012-02-23T16:04:13.110 に答える