服务器程序停留在发送

时间:2012-02-12 11:24:04

标签: c networking send

我正在用C构建服务器客户端模型。客户端连接到服务器并开始交换数据。但是,用户可以在程序中随时终止客户端,但不会通知服务器。即使在客户端关闭后,服务器也会继续发送该数据。 我的印象是,如果服务器无法发送数据,send函数将返回-1,但我的服务器程序只是停留在发送

if((byteSent = send(new_fd, fileContents,  strlen(fileContents), 0)) == -1){ //

程序在上面一行暂停。

我如何克服这个问题?

//代码

   exitT = 0;
    //execution_count = 1;
    for(i=0;i<execution_count;i++)
    {  
        sleep(time_delay);

        //getting the current time on the server machine
        time_t t;
        time(&t);

        char *time=ctime(&t);
        printf("The Execution time at server =  %s\n",time);

        system(exec_command);

       /*Open the file, get file size, read the contents and close the file*/

        // Open the file
        fp = fopen(fileName,"r");

        // Get File Size
        fseek(fp,0,SEEK_END);
        dataLength = ftell(fp);
        rewind(fp);                

        fileContents = (char*)malloc(dataLength+1);
       // Read File
       fread(fileContents,1,dataLength,fp);
       fileContents[dataLength] = '\0';

        // Close file
         fclose(fp);    

       printf("sockfd = %d \n",new_fd);
       // send file length to client
       rc=send(new_fd, &dataLength,  sizeof(dataLength), 0) ;

       printf("length of client data = %d \n",rc);

        printf("sockfd = %d \n",new_fd);
       // send time to client
       rc=send(new_fd, time,  strlen(time), 0) ;

       printf("length of client time = %d \n",rc);

       usleep(20000);

       // Send file contents to Client
       while(dataLength>0){
            printf("sockfd = %d \n",new_fd);
            if((byteSent = send(new_fd, fileContents,  strlen(fileContents), 0)) == -1){
                printf("bytes sent = %d \n",byteSent);
                exitT = 1;
                break;
            }
            dataLength-=byteSent;
       }

       //Delete the log file 
       sprintf(deleteCommand,"rm %s",fileName);
       system(deleteCommand);
       if(exitT == 1)
           break;
     }

      bzero(fileName,sizeof(fileName));
      bzero(exec_command,sizeof(exec_command));
      bzero(deleteCommand,sizeof(deleteCommand));

      //decClientNum();
      kill(parent_id,SIGALRM);
      close(new_fd);  // parent doesn't need this
      printf("STATUS = CLOSED\n");

      exit(0);
  }   

由于

4 个答案:

答案 0 :(得分:1)

我假设您正在为Linux或Posix系统编码。

send之类的系统调用失败时,返回-1并且设置errno ;你很可能应该使用errno来找出它失败的原因。

您可以使用strace找出您的服务器或其他系统调用所执行的系统调用。当然,也可以使用gdb调试器。

您可能需要多路复用输入或输出。系统调用pollselect(以及相关ppollpselect)。阅读例如select_tut(2)手册页。

您可能希望使用(或至少研究源代码)现有的面向事件的库,如libeventlibev等。(Gtk和Qt框架也提供了自己的,甚至可以在GUI应用程序之外使用。)

我强烈建议您阅读advanced unix programmingunix network programing(也许还有advanced linux programming)。

答案 1 :(得分:0)

也许您正在使用tcp协议,服务器正在等待ACK。如果您希望连接是异步的,请尝试使用udp。

答案 2 :(得分:0)

从手册页:send()中没有隐含传递失败的迹象。本地检测到的错误由返回值-1表示。

这样的事情可能有所帮助:http://stefan.buettcher.org/cs/conn_closed.html

答案 3 :(得分:0)

我认为我在派对上已经很晚了,但我认为这个答案可能对某人有所帮助。

如果发送套接字上没有空间来保存要传输的消息,并且套接字文件描述符没有设置O_NONBLOCK,则send()将阻塞,直到空间可用。

当send()函数卡住时,可能会出现这样的情况:TCP窗口大小已经变为0.当连接的另一端没有消耗接收到的数据时会发生这种情况。

可能存在这样的情况,接收端进程正在由GDB运行并且发生了段错误。

  1. TCP连接仍然存在。
  2. 正在不断发送数据。
  3. 接收方端没有消耗它。
  4. 因此,接收器TCP窗口大小将继续减小,您可以发送数据直到它大于零。一旦它变为0,send()函数将永远停滞。

    由于问题中提到的情况不是封闭连接的情况。当进程在封闭的TCP连接上写入某些内容时,它会收到SIGPIPE信号。 SIGPIPE的默认处理程序终止进程。因此,在一个封闭的连接场景中,如果您没有使用自己的SIGPIPE处理程序,那么只要在套接字上写入了某些内容,就应该通过默认处理程序终止进程。