服务器无法从客户端接收消息

时间:2013-04-05 14:21:48

标签: c sockets unix client-server

我正在使用Ubuntu 12.05。我一直在尝试通过C套接字编程实现Stop和wait协议。我创建了两个程序,一个是服务器,另一个是客户端。通过评论

解释了代码的预期工作

serversocket.c

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

int main(int argc,char *argv[])
{
    int listenfd = 0,qlength=10,connfd = 0,t=5;
    int n;
    struct sockaddr_in serv;
        struct sockaddr_in dest;
        socklen_t socksize = sizeof(struct sockaddr_in);
    char sendBuff[1024]="hi\n";
    //time_t ticks;
     listenfd = socket(AF_INET,SOCK_STREAM,0); //socket for listening to connection requests

     memset(&serv,'0',sizeof(serv));
     serv.sin_family = AF_INET;
     serv.sin_addr.s_addr = htonl(INADDR_ANY);
     serv.sin_port=htons(5000);

     bind(listenfd,(struct sockaddr *)&serv,sizeof(serv)); //binding the socket to a port
     listen(listenfd,2);    
     connfd=accept(listenfd,(struct sockaddr *)&dest,&socksize);  //another socket for sending and receiving on the previously built socket
         while(connfd){
         printf("Incoming connection from %s-sending a hi...\n",inet_ntoa(dest.sin_addr));
         send(connfd,sendBuff,strlen(sendBuff),0);         //at first my server sends a hi
         sleep(3);
         n=recv(connfd,sendBuff,1024,0);                  //if hi received by the client,then server should receive "Message Received" from the client
         sendBuff[n]='\0';
         printf("%s",sendBuff);
        connfd=accept(listenfd,(struct sockaddr *)&dest,&socksize); }

    return 0;
}

clientsocket.c

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

int main(int argc, char *argv[])
{
    int sockfd = 0, n = 0,m=2;
    char recvBuff[1024];
    struct sockaddr_in serv_addr; 

    if(argc != 2)
    {
        printf("\n Usage: %s <ip of server> \n",argv[0]);
        return 1;
    } 

    memset(recvBuff, '0',sizeof(recvBuff));
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    } 

    memset(&serv_addr, '0', sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(5000); 

    if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
    {
        printf("\n inet_pton error occured\n");
        return 1;
    } 

    if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
       printf("\n Error : Connect Failed \n");
       return 1;
    } 
   while(m--){                                      //m is 2 initially,I want that sending and receiving should be done 2 times
    n = recv(sockfd,recvBuff,1024,0);
    recvBuff[n]='\0';                               //"hi" is received
    printf("%s",recvBuff);                           

    if(recvBuff=="hi\n")
      send(sockfd,"Message Received",strlen("Message Received\n"),0);} //sending "Message received"


    return 0;
}

现在从服务器向客户端发送消息的工作正常,但是客户端到服务器(收到消息)正在产生问题。无论是给出错误还是正确结果,它只是给出一个空白屏幕。

2 个答案:

答案 0 :(得分:1)

您无法使用“==”运算符比较字符串。

您需要使用strcmp()

...所以

if( strcmp( recvBuff, "hi\n" ) == 0 )
    send(sockfd,"Message Received",strlen("Message Received\n"),0);
else
    printf( "[%s] != [hi\n]\n", recvBuff );

答案 1 :(得分:1)

基本上,您的代码中有三个不同的问题:

  1. 字符串比较(由K Scott Piel修复)。
  2. 收到的消息的打印件没有出来。您需要在所有'\n'个功能中添加printf
  3. 这是最重要的问题:在服务器和客户端之间的第一次通信之后,您在服务器代码中调用accept函数。从man accept page开始,我们可以阅读
  4.   

    accept()函数将提取第一个连接   挂起连接队列,创建一个具有相同套接字的新套接字   键入协议和地址族作为指定的套接字,并分配   该套接字的新文件描述符。

    因此,在第一次通信之后,您的服务器正在等待新连接,并且您的客户端正在等待来自服务器的消息。第二次沟通永远不会发生。

    要解决此问题,您可以使用fork() API。

    以下是使用fork()的修正提案:

    clientsocket.c

    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <arpa/inet.h> 
    
    int main(int argc, char *argv[])
    {
        int sockfd = 0, n = 0,m=2;
        char recvBuff[1024];
        struct sockaddr_in serv_addr; 
    
        if(argc != 2)
        {
            printf("\n Usage: %s <ip of server> \n",argv[0]);
            return 1;
        } 
    
        memset(recvBuff, '0',sizeof(recvBuff));
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
            printf("\n Error : Could not create socket \n");
            return 1;
        } 
    
        memset(&serv_addr, '0', sizeof(serv_addr)); 
    
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(5000); 
    
        if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
        {
            printf("\n inet_pton error occured\n");
            return 1;
        } 
    
        if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
        {
           printf("\n Error : Connect Failed \n");
           return 1;
        } 
    
       //m is 2 initially,I want that sending and receiving should be done 2 times
       while(m--)
       {
            printf("Waiting from the server ...\n");
            n = recv(sockfd,recvBuff,1024,0);
            recvBuff[n]= '\0';                               //"hi" is received
            printf("%s\n", recvBuff);                           
    
            if(!strncmp(recvBuff, "hi\n", strlen("hi\n")))
            {
                printf("Send ACK\n");
                n = send(sockfd,"Message Received",strlen("Message Received\n"),0);
                printf("%d Sent ... \n", n);
            }
        } //sending "Message received"
    
    
        return 0;
    }
    

    serversocket.c

    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <error.h>
    #include <string.h>
    #include <sys/types.h>
    #include <time.h>
    
    int main(int argc,char *argv[])
    {
        int listenfd = 0,qlength=10,connfd = 0,t=5;
        int n;
        struct sockaddr_in serv;
        struct sockaddr_in dest;
        socklen_t socksize = sizeof(struct sockaddr_in);
        char sendBuff[1024]="hi\n";
        pid_t  pid;
        int m = 2;
        //time_t ticks;
        listenfd = socket(AF_INET,SOCK_STREAM,0); //socket for listening to connection requests
    
        memset(&serv,'0',sizeof(serv));
        serv.sin_family = AF_INET;
        serv.sin_addr.s_addr = htonl(INADDR_ANY);
        serv.sin_port=htons(5000);
    
        bind(listenfd,(struct sockaddr *)&serv,sizeof(serv)); //binding the socket to a port
    
        printf("Server started ...\n");
        listen(listenfd,2);
        connfd=accept(listenfd,(struct sockaddr *)&dest,&socksize);  //another socket for sending and receiving on the previously built socket
        while(connfd > 0)
        {   
            printf("Incoming connection from %s-sending a hi...\n",inet_ntoa(dest.sin_addr));
            pid = fork();
            if(pid) {
                /* shall continue to listen to new client */
                printf("Parent shall continue listening ... \n");
                connfd=accept(listenfd,(struct sockaddr *)&dest,&socksize);
            } else {
                printf("Chlid process: Communication with the client ... \n");
                while(m--)
                {
                    printf("try %d - Sending %s ... \n", m, sendBuff);
                    send(connfd,sendBuff,strlen(sendBuff),0);         //at first my server sends a hi
                    sleep(3);
                    n=recv(connfd, sendBuff, 1024, 0);                  //if hi received by the client,then server should receive "Message Received" from the client
                    sendBuff[n]='\0';
                    printf("Data received: [%s]\n", sendBuff); /* need to add '\n' so the print will be displayed */
                    strcpy(sendBuff, "hi\n");
                }
                printf("Child process will exit\n");
                return 0;
            }        
        }
    
    
        return 0;
    }