0

我正在使用 Ubuntu 12.05。我一直在尝试通过 C 套接字编程实现停止和等待协议。我创建了两个程序,一个以服务器为特色,另一个以客户端为特色。通过注释解释代码的预期工作

服务器socket.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;
}

客户端socket.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;
}

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

4

2 回答 2

1

您不能使用“==”运算符比较字符串。

你需要使用strcmp()

所以....

if( strcmp( recvBuff, "hi\n" ) == 0 )
    send(sockfd,"Message Received",strlen("Message Received\n"),0);
else
    printf( "[%s] != [hi\n]\n", recvBuff );
于 2013-04-05T14:24:41.487 回答
1

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

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

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

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

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

这是使用以下方法的修复建议fork()

客户端socket.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;
}

服务器socket.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;
}
于 2013-04-05T15:23:55.817 回答