2017-07-11 3 views
0
//serv.c 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <getopt.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <poll.h> 
#include <signal.h> 
#include <string.h> 
#include <sys/wait.h> 
int main(int argc, char *argv[]) 
{ 

    FILE *log; 
    int port_no; 
    struct sockaddr_in server_addr; 
    struct hostent* server; int port_flag=0; 
    int c; 
    while(1) 
    { 
     static struct option long_options[]= 
     { 
      {"port",required_argument,0,'p'}, 
      {"log",required_argument,0,'l'}, 
     }; 
     c= getopt_long(argc,argv,"p:l",long_options,NULL); 
     if(c==-1) 
      break; 
     switch(c) 
     { 
      case 'l': 
       if(optarg) 
       { 
        if(optarg[0]!='-') 
        { 
         log= fopen(optarg,"w"); 
        } 
        else 
        { 
         fprintf(stderr,"log requires argument\n"); 
        } 

       } 
       break; 
      case 'p': 
       if(optarg) 
       { 
        if(optarg[0]!='-') 
        { 
         port_no= atoi(optarg); 
         port_flag=1; 
        } 
        else{ 
         printf("Usage --port=PORT_NUMBER\n"); 
        } 
       } 
       else 
       { 
        printf("Usage --port=PORT_NUMBER\n"); 
       } 
       break; 
      case '?': 
       write(STDOUT_FILENO,"\r",1); 
       exit(1); 
       break; 
      default: 
       break; 

     } 

    } 

int opt = 0, port_num, client_len; 
    struct sockaddr_in server_addr, client_addr; 
    socket_fd = socket(AF_INET, SOCK_STREAM, 0); 
    if(socket_fd < 0) { perror("Error opening socket"); exit(1); } 
    memset((char*) &server_addr, 0, sizeof(server_addr)); 
    server_addr.sin_family = AF_INET; 
    server_addr.sin_port = htons(port_num); 
    server_addr.sin_addr.s_addr = INADDR_ANY; 
    if(bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) 
    { 
     perror("Error binding socket"); 
     exit(1); 
    } 
    listen(socket_fd,5); 
    client_len=sizeof(client_addr); 
    newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len); 
    printf("accepting"); 
    if(newsocket_fd<0) 
    { 
     fprintf(stderr,"error on accept"); 

    } 
    char buffer[256]; 
    memset(buffer,0,256); 
    int n=read(newsocket_fd,buffer,255); 
    if(n<0) 
    { 
     fprintf(stderr,"Error reading from socket"); 

    } 
    printf("Here is the message: %s\n",buffer); 
    n=write(newsocket_fd,"I got your message",18); 
} 

いるclient.c私は理由を知りませんが、サーバーがからソケット の接続を受け入れていないような接続

int main(int argc, char *argv[]) 
{ 

    FILE *log; 
    int port_no; 
    struct sockaddr_in server_addr; 
    struct hostent* server; int port_flag=0; 
    int c; 
    while(1) 
    { 
     static struct option long_options[]= 
     { 
      {"port",required_argument,0,'p'}, 
      {"log",required_argument,0,'l'}, 
     }; 
     c= getopt_long(argc,argv,"p:l",long_options,NULL); 
     if(c==-1) 
      break; 
     switch(c) 
     { 
      case 'l': 
       if(optarg) 
       { 
        if(optarg[0]!='-') 
        { 
         log= fopen(optarg,"w"); 
        } 
        else 
        { 
         fprintf(stderr,"log requires argument\n"); 
        } 

       } 
       break; 
      case 'p': 
       if(optarg) 
       { 
        if(optarg[0]!='-') 
        { 
         port_no= atoi(optarg); 
         port_flag=1; 
        } 
        else{ 
         printf("Usage --port=PORT_NUMBER\n"); 
        } 
       } 
       else 
       { 
        printf("Usage --port=PORT_NUMBER\n"); 
       } 
       break; 
      case '?': 
       write(STDOUT_FILENO,"\r",1); 
       exit(1); 
       break; 
      default: 
       break; 

     } 

    } 
    char buffer[256]; 
      socket_fd = socket(AF_INET, SOCK_STREAM, 0); 
      if(socket_fd < 0) { perror("Error opening socket"); exit(0); } 
      server = gethostbyname("localhost"); 
      if(server == NULL) { fprintf(stderr, "Cannot find host"); exit(0); } 
      //Initialize the server address to zero and then correctly assign it 
      memset((char*) &server_addr,0, sizeof(server_addr)); 
      server_addr.sin_family = AF_INET; 
      memcpy((char *) &server_addr.sin_addr.s_addr, 
        (char*) server->h_addr, 
        server->h_length); 
      server_addr.sin_port = htons(port_no); 


if(connect(socket_fd,(struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { perror("Error connecting"); exit(0); } 
     printf("Please enter the message"); 
     memset(buffer,0,256); 
     fgets(buffer,255,stdin); 
     int n=write(socket_fd,buffer,strlen(buffer)); 
     if(n<0) 
     { 
      fprintf(stderr,"error writing to socket"); 
     } 
     memset(buffer,0,256); 
     n=read(socket_fd,buffer,255); 
     if(n<0) 
     { 
      printf("Error reading"); 
     } 
     printf("%s\n",buffer);} 

}

を受け入れるように見えるローカルホストdoesntの上のサーバークライアント。私は1024以上のポート番号を試しました。ただ は機能しません。ポート番号はユーザーが入力したものです。それが動作するport_noだけがありますか?

+0

あなたはどのようなエラーを得るか、そしてどこから? –

+0

エラーが発生しても、接続が確立されるまでハングし続けることはありません –

+0

テストで使用したACTUALコードはserv.cのport_numが初期化されていないと仮定します...まず "serv" "..."掛かった "... ... ??? – TonyB

答えて

1

投稿した "フルコード"は、コンパイルされないため完全ではありません(ヒント:client.cには1つのヘッダーファイルが含まれていません)。作られた些細な修正では、重要な手がかりが有効警告でコンパイルから来ている:その最後の警告で

$ gcc -g serv.c -o serv -Wall -Wextra 
serv.c: In function 'main': 
serv.c:94:71: warning: pointer targets in passing argument 3 of 'accept' differ in signedness [-Wpointer-sign] 
    int newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len); 
                    ^
In file included from serv.c:7:0: 
/usr/include/x86_64-linux-gnu/sys/socket.h:243:12: note: expected 'socklen_t * __restrict__' but argument is of type 'int *' 
extern int accept (int __fd, __SOCKADDR_ARG __addr, 
      ^
serv.c:79:5: warning: unused variable 'opt' [-Wunused-variable] 
int opt = 0, port_num, client_len; 
    ^
serv.c:23:36: warning: variable 'port_flag' set but not used [-Wunused-but-set-variable] 
    struct hostent* server; int port_flag=0; 
            ^
serv.c:23:21: warning: unused variable 'server' [-Wunused-variable] 
    struct hostent* server; int port_flag=0; 
        ^
serv.c:21:9: warning: variable 'port_no' set but not used [-Wunused-but-set-variable] 
    int port_no; 
     ^
serv.c:20:11: warning: variable 'log' set but not used [-Wunused-but-set-variable] 
    FILE *log; 
     ^
serv.c:111:1: warning: control reaches end of non-void function [-Wreturn-type] 
} 
^ 
serv.c:85:28: warning: 'port_num' may be used uninitialized in this function [-Wmaybe-uninitialized] 
    server_addr.sin_port = htons(port_num); 

ルック - 「port_numの」初期化されていませんか?上を見てください: "port_no"は初期化されていますが使用されていませんか?引数処理が無駄で、任意のポートでリッスンしているので、@Prasが "netstat -l -p"をチェックすると、これも表示されます。

デバッグ戦略として、賢明な警告でコンパイルする価値があります(そして、clangのような診断コンパイラを試してみてください)。一般的な開発戦略では、警告を有効にしてコードを実行する前に修正することで、デバッグに要する時間を短縮します。

0

ここでサーバーについて質問しているので、私が気づいたものです。

"port_no"と "port_num"の両方が宣言されている場合、ユーザーは "port_no"に割り当てられていますが、htons()を呼び出すときは "port_num"を使用しています。

あなたのスイッチケースの後に「SERVER_ADDR」の再宣言を持っている、ともnewsocket_fd

$gcc -o server server.c 
server.c: In function ‘main’: 
server.c:80:24: error: redeclaration of ‘server_addr’ with no linkage 
    struct sockaddr_in server_addr, client_addr; 
         ^~~~~~~~~~~ 
server.c:22:24: note: previous declaration of ‘server_addr’ was here 
    struct sockaddr_in server_addr; 
         ^~~~~~~~~~~ 
server.c:81:5: error: ‘socket_fd’ undeclared (first use in this function) 
    socket_fd = socket(AF_INET, SOCK_STREAM, 0); 
    ^~~~~~~~~ 
server.c:81:5: note: each undeclared identifier is reported only once for each function it appears in 
server.c:94:5: error: ‘newsocket_fd’ undeclared (first use in this function) 
    newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len); 

私はスイッチケースを取り外し、手動でそれを実行している取得するポート番号を割り当てられたいずれかの方法が欠落している、あなたがする必要がありますあなたの入力を確認して、さらにいくつかのエラーを解決してください。ここでは、コードの実際の例を示しています。

クライアントとしてnetcatを使用して接続をテストしました。

$ netcat 127.0.0.1 5555 
test message 
I got your message 

出力コードは指定したものと変更されていません。これは表示される内容です。改行のために "\ n"を使います。ここで

$gcc -o server server.c 
[email protected]:~$./server 
acceptingHere is the message: test message 

が変更されたコードです:

//serv.c 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <getopt.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <poll.h> 
#include <signal.h> 
#include <string.h> 
#include <sys/wait.h> 
int main(int argc, char *argv[]) 
{ 

    FILE *log; 
    // Added socket_fd and newsocket_fd 
    int socket_fd, newsocket_fd; 
    // use uint16_t for port number  
    uint16_t port_no; 
    //Removed struct sockaddr_in server_addr; 
    struct hostent* server; int port_flag=0; 
    int c; 

    port_no = 5555; 
    /* removed switch to show server does function 
    while(1) 
    { 
     static struct option long_options[]= 
     { 
      {"port",required_argument,0,'p'}, 
      {"log",required_argument,0,'l'}, 
     }; 
     c= getopt_long(argc,argv,"p:l",long_options,NULL); 
     if(c==-1) 
      break; 
     switch(c) 
     { 
      case 'l': 
       if(optarg) 
       { 
        if(optarg[0]!='-') 
        { 
         log= fopen(optarg,"w"); 
        } 
        else 
        { 
         fprintf(stderr,"log requires argument\n"); 
        } 

       } 
       break; 
      case 'p': 
       if(optarg) 
       { 
        if(optarg[0]!='-') 
        { 
         port_no= atoi(optarg); 
         port_flag=1; 
        } 
        else{ 
         printf("Usage --port=PORT_NUMBER\n"); 
        } 
       } 
       else 
       { 
        printf("Usage --port=PORT_NUMBER\n"); 
       } 
       break; 
      case '?': 
       write(STDOUT_FILENO,"\r",1); 
       exit(1); 
       break; 
      default: 
       break; 

     } 

    } 
    */ 

    // Removed port_num 
    int opt = 0, client_len; 
    struct sockaddr_in server_addr, client_addr; 
    socket_fd = socket(AF_INET, SOCK_STREAM, 0); 
    if(socket_fd < 0) { perror("Error opening socket"); exit(1); } 
    memset((char*) &server_addr, 0, sizeof(server_addr)); 
    server_addr.sin_family = AF_INET; 
    // using port_no in htons 
    server_addr.sin_port = htons(port_no); 
    server_addr.sin_addr.s_addr = INADDR_ANY; 
    if(bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) 
    { 
     perror("Error binding socket"); 
     exit(1); 
    } 
    listen(socket_fd,5); 
    client_len=sizeof(client_addr); 
    newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len); 
    printf("accepting"); 
    if(newsocket_fd<0) 
    { 
     fprintf(stderr,"error on accept"); 

    } 
    char buffer[256]; 
    memset(buffer,0,256); 
    int n=read(newsocket_fd,buffer,255); 
    if(n<0) 
    { 
     fprintf(stderr,"Error reading from socket"); 

    } 
    printf("Here is the message: %s\n",buffer); 
    n=write(newsocket_fd,"I got your message",18); 
} 
関連する問題