2015-03-12 5 views
0

Ниже приведена программа server.c. Когда я подключить клиента к серверу, сервер начинает цикл бесконечно в получать часть сообщенияПрограммирование сокетов TCP. Постоянное циклическое программирование сервера

Server.c

#include <unistd.h> 
#include <string.h> 
#include <stdio.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 

int main() 
{ 
    int sid,sid1,bin,lis,n,p,port, pid; 
    struct sockaddr_in sin,c; 
    socklen_t len; 
    char buffer[40]=""; 
    char buffer1[20]=""; 
    char ip[30]="192.168.65.241"; 
    // printf("\nEnter the IP Address :"); 
    // scanf("%s",ip); 
    printf("\nEnter the Port no.:"); 
    scanf("%d",&port); 
    sid=socket(AF_INET,SOCK_STREAM,0);//END POINT CONN, 
    if(sid<0) 
    { 
      perror("Socket : "); 
      exit(0); 
    } 
    printf("\nSocket created successfully..."); 
    sin.sin_family=AF_INET; 
    sin.sin_port=htons(port); 
    inet_aton(ip,&sin.sin_addr);//SERVER ADDRESS 
    bin=bind(sid,(struct sockaddr*)&sin,sizeof(sin));//BIND ADDRESS WITH SOCKET 
    if(bin<0) 
    { 
      perror("\nBind : "); 
      exit(0); 
    } 
    printf("\nBinding has been done successfully..."); 
    lis=listen(sid,10);//LISTEN TO THE CLIENT 
    if(lis<0) 
    { 
      perror("\nListen : "); 
      exit(0); 
    } 
    len=sizeof(c); 

    while(1){ 

     printf("A Client is connected to the server....."); 
     sid1=accept(sid,(struct sockaddr*)&sin,&len);//ACCEPT CONN.FROM CLIENT 
     if(sid1<1) 
     { 
      perror("\nAccept : "); 
      exit(0); 
     } 
     pid=fork();//CREATE PARENT AND CHILD PROCESS 

     if(pid<0){ 

      perror("ERROR on fork"); 
      exit(1); 
     } 
     if(pid==0){ 

      lis=listen(sid,10); 
      printf("\nEnter message...(Type END to terminate):\n"); 
      scanf("%s",buffer); 
      while(strcmp(buffer,"END")!=0) 
      { 
       send(sid,buffer,30,0);//SEND TO SERVER 
       scanf("%s",buffer); 
      } 
      send(sid,"END",5,0); 
      printf("\nTerminating the server...\n"); 
      exit(0); 
     } 
     else{ 

      n=recv(sid,buffer1,30,0);//RECEIVE FROM CLIENT 
      buffer[n]='\0'; 
      n=strcmp(buffer1,"END"); 
      while(strcmp(buffer1,"END")!=0) 
      { 
       **printf("\nClient: %s\n",buffer1);** // Infinite Looping 
       n=recv(sid,buffer1,30,0); 
      } 
      printf("\nA client has been disconnected from the server...\n");  
      exit(0); 
     } 
          close(sid); //CLOSE CONNECTIONS 
                     close(sid1); //CLOSE CONNECTIONS 


    } 
    shutdown(sid,2); //SHUTDOWN READ AND WRITE 
    close(sid); //CLOSE CONNECTIONS 
} 

Client.c

Клиентская программа не является проблемой .. Добавил код для вашей справки.

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <errno.h> 
int main() 
{ 
    int sid,bi,con,n,p,port; 
    char buffer[50],ip[30]; 
    sid=socket(AF_INET,SOCK_STREAM,0);//END POINT CONN. 
    if(sid==-1) 
    { 
      perror("\nSocket :"); 
     exit(0); 
    } 
    printf("A Socket created successfully...."); 
    struct sockaddr_in sin; 
    sin.sin_family = AF_INET; 
    printf("\nEnter the IP Address :"); 
    scanf("%s",ip); 
    printf("\nEnter the Port no. :"); 
    scanf("%d",&port); 
    sin.sin_port = htons(port); 
    inet_aton(ip,&sin.sin_addr); 
    con=connect(sid,(struct sockaddr*)&sin,sizeof(sin));//CONNECT TO SERVER 
    if(con == -1) 
    { 
     perror("Connection : "); 
      exit(0); 
    } 
    printf("\nConnection is successfull to the server(%s)....\n",ip); 
    p=fork(); 
    if(p) 
     { 
      printf("\nEnter message...(Type END to terminate):\n"); 
      scanf("%s",buffer); 
      while(strcmp(buffer,"END")!=0) 
      { 
        send(sid,buffer,30,0);//SEND TO THE SERVER 
        scanf("%s",buffer); 
      } 
      send(sid,"END",4,0); 
     printf("\nTerminating the client...\n"); 
     exit(0); 
     } 
     else 
     { 
       n=recv(sid,buffer,30,0);//RECV.FROM SERVER 
     printf("%d",n); 
     buffer[n+1]='\0'; 
      while(strcmp(buffer,"END")!=0) 
      { 
        printf("\nServer: %s\n",buffer); 
        n=recv(sid,buffer,30,0); 
      } 
      send(sid,"END",4,0); 
     exit(0); 
     } 
    printf("\nClient is terminated...\n"); 
    shutdown(sid,2);//SHUTDOWN READ AND WRITE 
    close(sid); //CLOSE CONNECTIONS 
} 

Пожалуйста, дайте мне знать решение как можно скорее.

+0

Первый запуск проверки на наличие ошибок, есть некоторые системные вызовы, которые вы не проверяете.Например, в дочернем процессе, почему вы вызываете 'listen' на сокет сервера? Этот вызов, скорее всего, потерпит неудачу. –

ответ

0

Вы используете неправильный сокет в запросах на чтение/запись в server.c.

В настоящий момент все вызовы на чтение/запись завершаются с ошибкой errno, указывающие, что сокет не подключен.

Вы должны использовать sid1, подключенный разъем, а не sid.

Вы также должны проверить возвращаемые значения, чтобы вы могли обнаруживать и обрабатывать ошибки.

1

Основная проблема, то есть бесконечный цикл просто потому, что recv() вызывается на главной сокет сервера (sid), а не сокет, возвращенный accept() - sid1. Изменить это:

n=recv(sid,buffer1,30,0);//RECEIVE FROM CLIENT 

в

n=recv(sid1,buffer1,30,0);//RECEIVE FROM CLIENT 

и

n=recv(sid,buffer1,30,0); 

в

n=recv(sid1,buffer1,30,0); 

и вы будете в бизнесе.

Есть и другие проблемы с кодом сервера:

  1. recv() это говорят, чтобы прочитать до 30 байтов в buffer1, однако, buffer1 составляет всего 20 байт - у вас есть буфер перерасход там ,
  2. Если клиент закрывает соединение без отправки «КОНЕЦ» и , то в цикле приема будет выполняться бесконечный цикл. Вы должны обнаружить закрытия соединения, которое обозначено recv() возвращающегося 0.
  3. listen() в настоящее время неоправданно называют в сервере, на линии 64.

Приведенный выше перечень вероятно не является исчерпывающим.

+0

Бесконечный цикл остановлен .. Но так как я написал несколько клиентов, принимающих сервер, это не так, пока я не закрываю текущего клиента, он готов принять следующего клиента ... Какое решение для этого? – Shirabthinath

+0

На самом деле, похоже, у вас есть это назад. Вы обрабатываете и обрабатываете получение данных в _parent_, а не _child_. 'fork()' возвращает 0 дочернему элементу, а id процесса - родительскому. В этом случае ваш принимающий код вызывает 'exit()', который завершает родительский. Я понятия не имею, что вы пытаетесь сделать в дочернем коде. – mhawke

Смежные вопросы