1

クライアントが切断されたときに、サーバーがクライアントからの新しい要求を受け入れる準備ができるようにプログラムを作成したいと思います。ここにコードがあります

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXLINE 100
#define LISTENQ 10

int main()
{
    int tmp, listenfd, connfd;
    int sin_size;
    struct sockaddr_in servaddr, cliaddr;
    char  buff[MAXLINE];
    time_t ticks;
    while(true)
    {
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = INADDR_ANY;
        servaddr.sin_port        = htons(13);
        memset(&(servaddr.sin_zero),'\0',8);
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenfd == -1){
           perror("error socket");
           exit(1);
          }

        tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
        if(tmp == -1){
            perror("error bind..");
            exit(1);
        }

        tmp=listen(listenfd, LISTENQ);
        if(tmp == -1){
            perror("error listen"); 
            exit(1);
        }

        sin_size = sizeof(struct sockaddr_in);    
        connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
        if(connfd == -1){
            perror("error accept"); 
            exit(1);
        }

        ticks = time(NULL);
        snprintf(buff,sizeof(buff),"Now Time: %.24s\r\n", ctime(&ticks));
        write(connfd, buff, strlen(buff));
        close(connfd);
        close(listenfd);
    }
}

この部分に問題が見つかりました

tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));

エラー: 'int*' から 'socklen_t* {aka unsigned int*}' への変換が無効です [-fpermissive]

connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);

エラー: 'int accept(int, sockaddr*, socklen_t*)' の引数 3 を初期化しています [-fpermissive]

それらの問題をどうすればいいですか?ポインタは正しくありませんでしたか?

4

4 に答える 4

1

宣言を変更する

 socklen_t  sin_size;  

これで問題は解決します。


最後の手段としてこれを試すこともできますが、上記の変更は問題なく機能します。

このステートメントを変更します

connfd=accept(listenfd,(struct sockaddr *)&cliaddr,(socklen_t * ) &sin_size);

見るman accept

@alk コメントを見た後、コメントからこの部分を追加しています。

特にポインターをキャストする場合、コンパイル時エラーをキャストするだけかもしれませんが、ポインターを逆参照するときにプログラムが期待するサイズが実際と異なるため、実行時にクラッシュする可能性が非常に高くなります。

于 2013-10-09T14:49:36.020 に答える
0

正解です。root アクセス ユーザーで実行する必要があります。

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>

#define MAXLINE 100
#define LISTENQ 10

int main()
{
    int tmp, listenfd, connfd;
    socklen_t sin_size;
    struct sockaddr_in servaddr, cliaddr;
    char  buff[MAXLINE];
    time_t ticks;
    while(true)
    {
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = INADDR_ANY;
        servaddr.sin_port        = htons(13);
        memset(&(servaddr.sin_zero),'\0',8);
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenfd == -1){
           perror("error socket");
           exit(1);
          }

        tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
        if(tmp == -1){
            perror("error bind..");
            exit(1);
        }

        tmp=listen(listenfd, LISTENQ);
        if(tmp == -1){
            perror("error listen"); 
            exit(1);
        }

        sin_size = sizeof(struct sockaddr_in);    
        connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
        if(connfd == -1){
            perror("error accept"); 
            exit(1);
        }

        ticks = time(NULL);
        snprintf(buff,sizeof(buff),"Sekarang pukul: %.24s\r\n", ctime(&ticks));
        write(connfd, buff, strlen(buff));
        close(connfd);
        close(listenfd);
    }
}
于 2013-10-09T15:10:52.083 に答える
0

C++ コンパイラの代わりに使用し、C コンパイラの代わりに使用しwhile(1)ます。while(true)

エラーは、C++ コンパイラを使用してソース コードをコンパイルすると発生します。C コンパイラを使用している場合、現在true定義されていないことを除いて、コードは前述のエラーを生成しません。

于 2013-10-09T14:33:59.753 に答える