TCP连接出错和意外行为

时间:2010-10-14 20:30:50

标签: c tcp

我希望我的TCP服务器和客户端能够相互“交谈”,具体取决于对方所说的内容。但是当我运行时,它似乎经历了一次迭代,但随后服务器和客户端似乎只是“挂起”。一旦我在客户端杀了它,我最终得到一个破坏的管道错误。

谁能解释我在这里做错了什么?

SERVER代码段:

while(feof(file_ptr) == 0)
{
    fscanf(file_ptr, "%s", supplies);
    printf("%s\n", supplies);

    //SEND supplies to all clients (currently just one client)

    n = write(newsockfd, supplies, strlen(supplies));

    if (n < 0)
    {
        error("ERROR writing to socket");
    }


    //Receive a request from client that they can use supply

    bzero(buffer,2);
    n = read(newsockfd,buffer,2);

    if (n < 0)
    {
        error("ERROR reading from socket");
    }

    printf("Who is using supply? %s\n", buffer);


    if(strcmp(buffer, "A"))
    {
        aRounds++;  
    }


    while(done != 1)
    {
        //WAIT loop until message CO is received from client
        bzero(buffer,2);
        n = read(newsockfd,buffer,2);

        if (n < 0)
        {
            error("ERROR reading from socket");
        }

        printf("Done? %s\n", buffer);



        if(strcmp(buffer, "CO"))
        {
            done = 1;
        }
    }

    done = 0;
}

fclose(file_ptr);
n = write(newsockfd, "DN", 2);

CLIENT代码段:

while(noSupplies != 1)
{
    //RECEIVE MSG from server about supplies
    bzero(buffer,2); 
    n = read(sockfd,buffer,2);

    if (n < 0) 
    {
        error("ERROR reading from socket");
    }

    printf("%s\n",buffer);

    if(strcmp(buffer, "BC") == 0 || strcmp(buffer, "CB") == 0)
    {
        //SEND server msg that you are using supply

        n = write(sockfd,"A", 1);
        if (n < 0)
        {
            error("ERROR writing to socket"); 
        }


        printf("Client A has received components %s during round %d.\n", buffer, round);


        n = write(sockfd,"CO", 2);
        if (n < 0)
        {
            error("ERROR writing to socket"); 
        }

    }
    else if(strcmp(buffer, "DN"))
    {
        noSupplies = 1;
    }

    round++;
}

我从服务器获取以下内容(在查杀之前):

BC
Who is smoking? A
Done smoking? CO

以下来自客户端(杀戮之前):

BC
Client A has received components BC during round 1.

然后在从客户端杀死之后......我从服务器获得以下内容:

BC
Who is using supply? A
Done? CO
Done? 
CB
Who is using supply? 
Done? 
CB
Who is using supply? 
Done? 
BC
Broken pipe

有谁知道我做错了什么? (寻找代码修复!)

仅仅是一个FYI ..我将最终更改服务器代码以处理多个客户端(TCP),但一次只有一个障碍? :S

谢谢!

2 个答案:

答案 0 :(得分:1)

不确定这是否是您的全部问题,但

bzero(buffer, 2);
n = read(socket, buffer, 2);

...

printf("%s", buffer);

是不正确的,因为如果读取实际上得到2个字节而且它们都不是0那么缓冲区可能不是空终止字符串(除非之前有某些事情这样做)。

strcmp的几次调用也应该总是因为同样的原因而失败 - 字符串中的读取不会被终止,因此strcmp认为它继续运行,因此与字符串相比不同,甚至如果第一个字母是相同的。

修改

 n = read(socket, buffer, 2);
 if (n<0) {
     die_horrible_death();
 }
 buffer[n] = 0; // since arrays are 0 indexed this should be after last read character
 printf("I just read: \"%s\"\n", buffer);

答案 1 :(得分:0)

您的服务器代码在开始时只向客户端写入一次内容。之后,在循环中 - 它只是读取。

OTOH您的客户端在循环中读写。

由于您在阻止模式下使用套接字 - 这意味着您的客户端最终会在调用recv时被阻止。

P.S。 没有违法行为 - 但你需要学习很多东西。

  1. TCP是一个隧道。当您的服务器通过一次调用向send / write发送2个字节的数据时 - 无法保证您的客户只需一次调用recv即可阅读此内容。
  2. 因此 - 读取和解析总是必须在某种循环中完成。
  3. 你不能只使用阻塞I / O编写一个非常强大的客户端/服务器,能够按需超时/中断。
  4. 学习,学习,学习
相关问题