c 如何结束socket读取

Posted

技术标签:

【中文标题】c 如何结束socket读取【英文标题】:c how to end socket reading 【发布时间】:2016-03-27 04:13:25 【问题描述】:

我正在尝试读取服务器,直到客户端发送完成消息。这是 myVar.id==-1。我在服务器中读取无限循环,直到它从客户端读取完成标志。它读取直到它从客户端完成标志,但它没有结束它挂在那里。有什么想法吗?

//server

sockdesc = socket(AF_INET, SOCK_STREAM, 0);
if ( sockdesc < 0 )

  cout << "Error creating socket" << endl;
  exit(0);

else
   if ( getaddrinfo("0.0.0.0", portnum, NULL, &myinfo) != 0 )
   
      cout << "Error getting address" << endl;
      exit(0);
   

if (bind(sockdesc, myinfo->ai_addr, myinfo->ai_addrlen) < 0 )
  cout << "Error binding to socket" << endl;
  exit(0);

if ( listen(sockdesc, 1) < 0 )
  cout << "Error in listen" << endl;
  exit(0);

connection = accept(sockdesc, NULL, NULL);
if ( connection < 0 )
  cout << "Error in accept" << endl;
  exit(0);

while(true)
    value = read(connection, (char*)&myVar, sizeof(procd));
    if (value < 0) 
      perror("ERROR reading from socket");
      exit(1);
    
    if(myVar.id==-1)
        close(connection);
        exit(0);
    //if
    else
        //display what received

               


//client
while ( getline (inputFile,line) )//read a line till EOF
       
    write(sockdesc, (char*)&myVar, sizeof(procd));  

myVar.id=-1;
write(sockdesc, (char*)&myVar, sizeof(procd));

【问题讨论】:

“挂在那里”到底是什么意思? Srver read() 似乎处于默认字节流模式,因此似乎无法正确和完整地处理 read() 返回的结果或处理任何消息协议。结果:“myVar”不太可能包含正确框架的应用程序协议单元,“id”可能是错误的。 如果read() 返回零,则对等方已关闭连接。你不是在为此测试。你应该。 【参考方案1】:

您还必须处理您的客户可能意外死亡的情况...... ...在这种情况下,READ 将返回零...

虽然你没有说明你使用的是什么平台,但是 Linux 上的手册页说: 如果 fildes 指的是一个套接字, read() 应该等同于没有设置标志的 recv()。

recv() 的手册页说:

返回值

成功完成后,recv() 将返回 以字节为单位的消息。如果没有可接收的消息并且 对等方已执行有序关闭,recv() 应返回 0。 否则返回-1并设置errno来表示错误。

您的代码无法处理 read 返回零的特殊情况。

【讨论】:

这些都是很好的观察结果,但它们没有回答问题。【参考方案2】:

您的代码并没有真正显示足够...注意,通过套接字发送结构很棘手,请参阅此

passing a struct over TCP (SOCK_STREAM) socket in C

这里有一些想法可能会有所帮助......

while ( getline (inputFile,line) )        
  write(sockdesc, (char*)&myVar, sizeof(procd));  

myVar.id=-1;
write(sockdesc, (char*)&myVar, sizeof(procd));

我假设myVar 在堆栈上声明如下procd myVar;

我不知道getline 在做什么,stdio 中的getline 需要三个参数?你用的是什么getline 函数,如果这是C,这可能是个问题?

getline 将数据放在哪里,指向getline 的参数之一是指向myVar 的指针吗?

我还必须假设它们在使用相同编译器的同一台机器上,因为在某些情况下发送二进制结构将不起作用,即如果你将它从 x86 发送到大端机器或打包的机器结构不同的事情将不起作用。请参阅我之前发布的链接。

说了这么多,你真的需要做更多的错误检查。我会尝试以下方法,看看它是否有效,然后从那里开始工作......

struct test 
  ssize_t id;
;
struct test payload;
payload.id=-1;  
write(sockdesc, (char*)&payload, sizeof(test));  

【讨论】:

以上是关于c 如何结束socket读取的主要内容,如果未能解决你的问题,请参考以下文章

C Pipe:父级在子级结束之前从子级读取

C语言文件读取fscanf(),该怎么处理

如何在java中识别InputStream的结束

readLine读取socket流的时候产生了阻塞

C++中怎么逐行读取数据

关于 recv 和读取缓冲区 - C Berkeley Sockets