4

Linux (UNIX) ソケットでのソケット プログラミングは初めてです。インターネットで、接続ごとにスレッドを生成する tcp サーバーの次のコードを見つけました。しかし、うまくいきません。accept() 関数は即座に戻り、接続を待ちません。私は何を間違っていますか?

これがコードです

int main(int argv, char *args[])
{
    struct sockaddr_in addr;
    int sd, port;

    port = htons(SERVER_PORT);

    /*--- create socket ---*/
    sd = socket(PF_INET, SOCK_STREAM, 0);
    if ( sd < 0 )
        panic("socket");

    /*--- bind port/address to socket ---*/
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = port;
    addr.sin_addr.s_addr = INADDR_ANY;                   /* any interface */
    if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
        panic("bind");

    /*--- make into listener with 10 slots ---*/
    if ( listen(sd, 10) != 0 )
        panic("listen")

    /*--- begin waiting for connections ---*/
    else
    {   int sd;
        pthread_t child;
        FILE *fp;

        while (1)                         /* process all incoming clients */
        {
            sd = accept(sd, 0, 0);     /* accept connection */
            fp = fdopen(sd, "wr+");           /* convert into FILE* */
            pthread_create(&child, 0, servlet, fp);       /* start thread */
            pthread_detach(child);                      /* don't track it */
        }
    }
} 
4

5 に答える 5

5

変数をシャドウしsd、無効なソケットを渡してaccept()すぐに失敗させます。

EBADF不正なファイル記述子を通知するために返される可能性があります。コードの戻り値をチェックすれば、お気づきでしょう。

このようなものをキャッチするには、より多くのコンパイラ警告を有効にする必要があります。GCC では、-Wshadowこのような警告を有効にするオプションを使用できます。

于 2013-01-08T15:21:53.350 に答える
2

accept()callの戻り値をチェックしていません。ほとんどの場合、エラーが返されます。

于 2013-01-08T15:21:53.547 に答える
2

sd 変数の再定義があります

int sd;
于 2013-01-08T15:22:48.437 に答える
0

いくつかの問題:

1) panic("listen") にコンマがありません

2) "sd" を 2 回宣言しています (1 つは main() で、もう 1 つはそれ以外で)。

#include <stdio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>

#define SERVER_PORT 30000

int main(int argv, char *args[])
{
    struct sockaddr_in addr;
    int sd, port;

    port = htons(SERVER_PORT);

    /*--- create socket ---*/
    sd = socket(PF_INET, SOCK_STREAM, 0);

    /*--- bind port/address to socket ---*/
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = port;
    addr.sin_addr.s_addr = INADDR_ANY;                   /* any interface */

    bind(sd, (struct sockaddr*)&addr, sizeof(addr));

    /*--- make into listener with 10 slots ---*/
    listen(sd, 10);

    /*--- begin waiting for connections ---*/
    pthread_t child;
    FILE *fp;

    while (1)                         /* process all incoming clients */
    {
        printf("before accept\n");
        sd = accept(sd, 0, 0);     /* accept connection */
        fp = fdopen(sd, "wr+");           /* convert into FILE* */
        //pthread_create(&child, 0, servlet, fp);       /* start thread */
        //pthread_detach(child);                      /* don't track it */
        printf("After accept\n");
    }

} 
于 2013-01-08T15:31:11.607 に答える
0

それらは変数 sd の再定義です。

int sd; // at line 3 and 26
于 2013-01-08T15:46:18.913 に答える