2014-02-25 3 views
0

Программирование сокетов для реализации простого клиента и сервера, которые обмениваются данными по сети и реализуют простую связь с клиентским сервером. Клиент открывает сеанс с сервером на предопределенном порту и затем предоставляет строку текстовых сообщений.Программирование сокетов TCP

Сервер выводит текстовое сообщение на стандартный вывод, а также продолжает работать, чтобы получать больше текстовых сообщений.

Когда клиент закрывает сеанс, выбирая вариант «Выход», соединение с сервером должно быть законно прекращено.

Когда сервер завершается нажатием кнопки C, сервер также должен изящно освободить открытый сокет.

Я сделал эту программу, но когда я ввожу строку и нажимаю кнопку ввода на стороне клиента, она не появляется на сервере, но когда я ввожу второй раз, появляется первый вход, а второй - в ожидании.

Второй один появляется, когда третий вход делается ...

Могу ли я получить решение этой проблемы ??

//Server.c 

int main() 
{ 
    int listenfd = 0; 
    int confd=0; 
    struct sockaddr_in sa; 
    char msg[1025]; 
char c[1]; 
     int i; 

    listenfd = socket(AF_INET,SOCK_STREAM,0); 
    if(listenfd<0) 
    { 
     perror("Socket"); 
     return 1; 
    } 
    sa.sin_family = AF_INET; 
    sa.sin_port = htons(1234); 
    sa.sin_addr.s_addr = htonl(INADDR_ANY); 

    while((bind(listenfd,(struct sockaddr*)&sa,sizeof(sa))<0)){return 1;} 
    printf("\nBind Successfull"); 

    listen(listenfd,10); 
     while(1){ 
     confd=accept(listenfd,(struct sockaddr*)NULL,NULL); 
     printf("\nConnected"); 
     memset(msg,0x0,10); 
     do{ 
       read(confd,c,1); 
       if(strcmp(c,"n")!=0) 
       { 
       read(confd,msg,10); 
       printf("\n%s",msg); 
       memset(msg,0x0,10); 
       } 
       else{ 
       confd=accept(listenfd,(struct sockaddr *)NULL,NULL); 
       printf("\nWaiting.."); 
       //close(confd); 

       } 

      // write(confd,msg,10); 
     //} 
     //msg[rc]='\0' 
     }while(1); 
     close(confd); 
    } 
} 

//Client.c 

int main() 
{ 

    int sock1= 0; 
    FILE *serv; 
    struct sockaddr_in server,clin; 
    char msg[1024],c[1]; 
    server.sin_family = AF_INET; 
    server.sin_port = htons(1234); 
    if(inet_pton(AF_INET,"192.168.125.7",&server.sin_addr)<0) 
    { 
     perror("inet_pton"); 
     return 1; 
    } 
    if((sock1 = socket(AF_INET,SOCK_STREAM,0))<0) 
    { 
     perror("socket"); 
     return 1; 
    } 
    if(connect(sock1,(struct sockaddr*)&server,sizeof(server))<0) 
    { 
     perror("Connect"); 
     return 1; 

    } 
     //printf("\nEnter 'y' to exit."); 
    while(1){ 
    // memset(&msg, '0', sizeof(msg)); 
     printf("\nDo you want to continue(y/n):"); 
     scanf(" %[^\n]",c); 
     if(strcmp(c,"y")==0){ 
       printf("\nEnter String:"); 

       scanf("%c",&c); 
       scanf(" %[^\n]",msg); 
       printf("\nSending String to server.."); 
       //scanf("%c",&c); 
       write(sock1,c,1); 
       write(sock1,msg,10); 
     } 
     if(strcmp(c,"n")==0) 
     { 
     write(sock1,c,10); 
     exit(1); 
     } 
    } 
    close(sock1); 
    printf("\n"); 
} 
+0

Внимательно прочитайте man-страницы для read()/write() и узнайте, что по крайней мере для сокетов эти две функции не обязательно читают/записывают столько байтов, сколько им было сказано, но мало. Таким образом, цикл вокруг таких вызовов, подсчитываемых до тех пор, пока все данные или терминаторы не были прочитаны/написаны, является хорошей идеей, не говоря уже о существенной необходимости. – alk

ответ

0

Программирование сокетов - непростая задача, особенно если вы хотите, чтобы код был неблокирующим. Я рекомендую вам использовать существующий код, а не писать его с нуля. Вы тратите много времени, изобретая колесо!

Здесь вы найдете потолочный класс C++ Socket в одном файле * .cpp с демонстрационным приложением, которое показывает вам, что вы можете отправлять и получать строки в обоих направлениях, вы даже можете подключиться к серверу Telnet с помощью демонстрационного приложения и более ...

http://www.codeproject.com/Articles/34163/A-Universal-TCP-Socket-Class-for-Non-blocking-Serv

Этот код утвержден, так как лет работать без каких-либо проблем. Я использую его в коммерческом продукте и могу заверить, что он является доказательством пули.

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