读取句柄问题 [英] read handle problem
问题描述
我正在使用epoll进行网络编程,我有这个代码...
buf,bufsize);
我有一个巨大的缓冲区大小,我认为它会接收客户端发送的一切。
一个例子是,如果一个客户端发送了500字节,但它不知何故进入了两个250字节的数据包,那么是没办法处理这种情况的。
我在网上查找并找到此代码
int handle_read client * cli,struct epoll_event * ev){
size_t len = 4096;
char * p;
ssize_t received;
cli-> state = 1;
if(cli-> buffer!= NULL){
// free(cli-> buffer);
// printf(Buff not null%s\\\
,cli-> buffer);
}
//为数据分配空间
cli-> buffer =(char *)malloc((size_t)(sizeof(char)* 4096)
p = cli-> buffer;
do {//读直到循环条件
received = recv(ev-> data.fd,p,len,0);
if(received< 0& errno!= EAGAIN&& errno!= EWOULDBLOCK){
//如果错误,从epoll中删除并关闭socket
printf处理错误!\\\
Client disconnect!\\\
);
epoll_ctl(epollfd,EPOLL_CTL_DEL,ev-> data.fd,ev);
close(ev-> data.fd);
}
p =& cli-> buffer [received];
} while(received> = len&&& errno!= EAGAIN&& errno!= EWOULDBLOCK);
return received;
}
你们认为它能处理接收时可能发生的所有异常吗?也可以请提供处理套接字异常的教程或示例?在线示例代码不包含详细信息..提前感谢
recv
可以返回任何三个内容,您的代码需要正确处理每个
1)正数。这意味着它读取了一些字节。
2)负数。这意味着发生了错误。
3)零。这意味着连接的另一端在套接字上执行成功的 shutdown()
(或 close()
)。 (通常,从read()或recv()返回0意味着 EOF
。)
<错误情况进一步分解为
EAGAIN
或 EWOULDBLOCK
和其他一切。前两个只是意味着它是一个非阻塞的套接字,没有数据,给你在这个时候。你可能想回去再次调用poll()(或select()或epoll()),以避免繁忙的等待... 其他真正的错误。你需要处理这些;有关完整列表,请参见 POSIX规范recv()。 p>
鉴于这一切,我会说你的示例代码是坏的有几个原因。它不能正确处理0(关闭连接)。它不处理任何错误。当 recv()
返回 EAGAIN
/ EWOULDBLOCK
。
哦,它使用 sizeof(char)
由不熟悉C或C ++编程语言的人编写。
I am working on network programming using epoll and I have this code...
int read = read(socket, buf, bufsize);
I have a huge buffer size and I assumed it will receive everything clients sent. However, I started facing problems like packet segmentation.
One example is that if a client sent 500 bytes but it somehow got into two 250 bytes packets then there is no way to handle this situation.
I looked up online and found this code
int handle_read(client *cli, struct epoll_event *ev) {
size_t len = 4096;
char *p;
ssize_t received;
cli->state = 1;
if (cli->buffer != NULL) {
//free(cli->buffer);
//printf("Buff not null %s\n", cli->buffer);
}
//allocate space for data
cli->buffer = (char*)malloc( (size_t)(sizeof(char) * 4096) );
p = cli->buffer;
do { //read until loop conditions
received = recv(ev->data.fd, p, len, 0);
if (received < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
//if error, remove from epoll and close socket
printf("Handle error!!!\nClient disconnected!\n");
epoll_ctl(epollfd, EPOLL_CTL_DEL, ev->data.fd, ev);
close(ev->data.fd);
}
p = &cli->buffer[received];
} while (received >= len && errno != EAGAIN && errno != EWOULDBLOCK);
return received;
}
Do you guys think it handles all the exceptions might happen while receiving? Also could you please provide me tutorials or examples that handles socket exceptions? Sample codes online don't cover details.. Thanks in advance
recv
can return any of three things, and your code needs to handle each one correctly:
1) Positive number. This means it read some bytes.
2) Negative number. This means an "error" occurred.
3) Zero. This means the other end of the connection performed a successful shutdown()
(or close()
) on the socket. (In general, a return of 0 from read() or recv() means EOF
.)
The "error" case further breaks down into "EAGAIN
or EWOULDBLOCK
" and "everything else". The first two just means it is a non-blocking socket and there was no data to give you at this time. You probably want to go back and call poll() (or select() or epoll()) again to avoid busy waiting...
"Everything else" means a real error. You need to handle those too; see the POSIX spec for recv() for a complete list.
Given all this, I would say your sample code is bad for several reasons. It does not handle 0 (closed connection) properly. It does not handle any errors. It does a busy-loop when the recv()
returns EAGAIN
/EWOULDBLOCK
.
Oh, and it uses sizeof(char)
, which is a sure sign it was written by somebody who is not familiar with the C or C++ programming languages.
这篇关于读取句柄问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!