2012-02-12 127 views
0

我正在用C语言构建服务器客户端模型。客户端连接到服务器并开始交换数据。但是,用户可以随时在程序中结束客户端,但服务器不会收到通知。即使客户端关闭后,服务器也会继续发送该数据。 我是在发送函数将返回-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); 
    } 

感谢

+0

请显示更多代码。 – ThiefMaster 2012-02-12 11:31:20

回答

1

我假设你是编码为Linux或POSIX系统。

当像send系统调用失败,它返回-1和设置errno;你很可能应该使用errno找出失败的原因。

你可以使用strace找出哪些系统调用是由您的服务器,或者一些其他的一个实现。当然,也可以使用gdb调试器。

你很可能需要复用输入或输出。系统调用的是poll,select(和相关的ppollpselect)。阅读例如select_tut(2)手册页。

您可能需要使用(或至少研究的源代码)现有的面向事件库,例如libeventlibev等。(无论基于GTK和Qt框架,也提供他们自己,可能连外GUI的使用应用程序)。

我强烈建议阅读关于advanced unix programmingunix network programing(也可能约advanced linux programming)。

+0

通常人们不能在家庭作业中使用这样的库。它几乎无法达到使用底层套接字函数并学习如何使用它们的目的。 – ThiefMaster 2012-02-12 11:32:01

+0

但他们至少可以学习他们的源代码并学习很多东西。 – 2012-02-12 11:38:28

+0

的确如此 - 但对于简单的任务来说,它通常太复杂。 – ThiefMaster 2012-02-12 11:39:05

0

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

+0

这是我的网络任务的一部分,我必须使用TCP – 2012-02-12 11:29:12

0

从手册页:未交付的任何指示是在发送隐式的()。本地检测到的错误由返回值-1指示。

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

+0

该示例显示服务器正在从客户端接收一些内容,并且如果管道中没有任何内容,它会将客户端关闭。但在我的程序中,客户端在服务器向客户端发送数据时关闭。我的服务器程序在send()函数中暂停。并且接收标志对send()函数不起作用。 – 2012-02-12 21:32:54

0

我觉得我是在党的相当晚了,但我想这个答案可能会帮助别人。

如果没有可用空间在发送插座持有待发送的消息,和插座文件描述符没有O_NONBLOCK集,发送()应被阻塞,直到可用空间。

当发送()函数卡住,可能有情况怎么样,TCP窗口大小变为0时,连接的另一端没有消耗接收到的数据它发生。

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

  1. TCP连接保持建立状态。
  2. 数据正在不断发送。
  3. 接收端没有使用它。

因此,接收方的TCP窗口大小将继续下降,您可以发送数据直到它大于零。一旦变为0,send()函数就会永久卡住。

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