errno == EAGAIN || errno == EWOULDBLOCK
时间: 2023-08-25 15:08:20 浏览: 122
这个条件判断通常用于检查非阻塞 I/O 操作返回的错误码。当 errno 的值为 EAGAIN 或者 EWOULDBLOCK 时,表示当前操作被阻塞,但是可以稍后再次尝试。
EAGAIN 和 EWOULDBLOCK 的值通常是相等的,它们表示的含义也是一样的。在非阻塞模式下,如果操作无法立即完成(例如读取或写入操作),系统会返回这两个错误码之一,以告知调用者稍后再试。
因此,这个条件判断可以用来判断当前操作是否被阻塞,如果是,则可以进行一些额外的处理(例如等待一段时间后再次尝试),或者将操作放入等待队列中。
相关问题
ssize_t num_bytes = read(datapacket.clientSockfd,&ReceivePackets,sizeof(ReceivePackets)); CON_LOG("==="); if (num_bytes > 0) { // 成功读取了一定数量的数据 CON_LOG("###read######Read %zd bytes,fd:%d,chooice:%s cmdBuf:%s# returnValue:%s",num_bytes,ReceivePackets.clientSockfd,ReceivePackets.choose,ReceivePackets.cmdBuf,ReceivePackets.returnValue); } else if (num_bytes == 0) { // 对端关闭了连接 CON_LOG("Connection closed\n"); } else if (errno == EAGAIN || errno == EWOULDBLOCK) { // 当前没有数据可读 CON_LOG("No data available\n"); } else { // 出现了错误 perror("read"); return -1; }这样写对了么
你的代码在处理 `read()` 函数返回值的情况方面是正确的。下面是对你的代码进行解释:
```c
ssize_t num_bytes = read(datapacket.clientSockfd, &ReceivePackets, sizeof(ReceivePackets));
CON_LOG("===");
if (num_bytes > 0) {
// 成功读取了一定数量的数据
CON_LOG("###read######Read %zd bytes,fd:%d,chooice:%s cmdBuf:%s# returnValue:%s",
num_bytes, ReceivePackets.clientSockfd, ReceivePackets.choose, ReceivePackets.cmdBuf, ReceivePackets.returnValue);
} else if (num_bytes == 0) {
// 对端关闭了连接
CON_LOG("Connection closed\n");
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
// 当前没有数据可读
CON_LOG("No data available\n");
} else {
// 出现了错误
perror("read");
return -1;
}
```
你正确地使用了 `num_bytes` 来判断 `read()` 函数的返回情况。当 `num_bytes` 大于 0 时,表示成功读取了一定数量的数据,你可以在这个分支中对读取到的数据进行进一步处理。当 `num_bytes` 等于 0 时,表示对端关闭了连接,你可以相应地进行处理。当 `errno` 为 `EAGAIN` 或 `EWOULDBLOCK` 时,表示当前没有数据可读,你可以继续等待或进行其他操作。当 `read()` 返回值小于 0 并且 `errno` 不是 `EAGAIN` 或 `EWOULDBLOCK` 时,表示出现了错误,你使用 `perror()` 输出错误信息并返回 -1。
总体而言,你的处理方式是正确的,可以根据不同的返回情况进行相应的操作。如果你的代码在实际运行中没有问题,那么这样的写法是正确的。
如果你还有其他问题,请随时向我提问。
enum Choose { TcpHeartbeat=200, TcpExeCmd, TcpSendCmd }; // 定义结构体 struct DataPacket { int clientSockfd; enum Choose choose; char *cmdBuf; char *returnValue; }; struct DataPacket datapacket; struct DataPacket ReceivePackets; int InitializePointer(char option[]) { next: if (strstr(option, "init")) { ReceivePackets.cmdBuf = calloc(BUFFER_SIZE, sizeof(char)); ReceivePackets.returnValue = calloc(BUFFER_SIZE, sizeof(char)); datapacket.cmdBuf = calloc(BUFFER_SIZE, sizeof(char)); datapacket.returnValue = calloc(BUFFER_SIZE, sizeof(char)); if (ReceivePackets.cmdBuf == NULL || ReceivePackets.returnValue == NULL || datapacket.cmdBuf == NULL || datapacket.returnValue == NULL) { CON_LOG("memory allocation failed"); goto next; } } else if (strstr(option, "free")) { free(datapacket.cmdBuf); datapacket.cmdBuf = NULL; free(ReceivePackets.returnValue); ReceivePackets.returnValue = NULL; free(datapacket.cmdBuf); datapacket.cmdBuf = NULL; free(ReceivePackets.cmdBuf); ReceivePackets.cmdBuf = NULL; } return 1; } int WriteServer(){ ssize_t bytes_written = write(datapacket.clientSockfd , &datapacket,sizeof(datapacket)); if (bytes_written == -1) { perror("Write error"); goto fail; } else if (bytes_written < sizeof(datapacket)){ CON_LOG("Only partial data was written"); goto fail; } else { CON_LOG("Write successful"); CON_LOG("Write#fd:%d# choose:%d# cmdBuf:%s# returnValue:%s#",datapacket.clientSockfd,datapacket.choose,datapacket.cmdBuf,datapacket.returnValue); } InitializePointer("free"); return 1; } int PerformServerTransfer(int server_client_sockfd) { char str_msg_code[SMALL_STR_LEN]={0}; int msg_code=0,code=0,ret=1; char cmd[TEMP_STR_LEN] = {0}; char *SendString = NULL; char resultbuf[LONG_BUFF_LEN] = {0}; datapacket.clientSockfd = server_client_sockfd; if(!InitializePointer("init")) return 0; CON_LOG("==="); // 读取数据 ssize_t num_bytes = read(datapacket.clientSockfd,&ReceivePackets,sizeof(ReceivePackets)); CON_LOG("==="); if (num_bytes > 0) { // 成功读取了一定数量的数据 CON_LOG("==="); CON_LOG("###read######fd:%d,cmdBuf:%s# returnValue:%s",ReceivePackets.clientSockfd,ReceivePackets.cmdBuf,ReceivePackets.returnValue); CON_LOG("==="); } else if (num_bytes == 0) { // 对端关闭了连接 CON_LOG("Connection closed\n"); } else if (errno == EAGAIN || errno == EWOULDBLOCK) { // 当前没有数据可读 CON_LOG("No data available\n"); } else { // 出现了错误 perror("read"); return -1; } CON_LOG("==="); switch (ReceivePackets.choose) { case TcpHeartbeat: datapacket.choose=TcpHeartbeat; if(ReceivePackets.returnValue != NULL && strlen(ReceivePackets.returnValue)){ sprintf(cmd,"echo %s > /tmp/returnValue",datapacket.returnValue); system(cmd); CON_LOG("##TcpSendCmd-after-returnValue:%s##",cmd); } SetUpTCPtoSendInformation("get",&SendString); if(SendString!= NULL && strlen(SendString)){ datapacket.choose=TcpExeCmd; free(datapacket.cmdBuf); datapacket.cmdBuf=malloc(strlen(SendString) + 1); strcpy(datapacket.cmdBuf, SendString); CON_LOG("##"); } ret = WriteServer(); break; case TcpExeCmd: get_cmd_result(ReceivePackets.cmdBuf, resultbuf, sizeof(resultbuf)); datapacket.choose=TcpHeartbeat; free(datapacket.returnValue); datapacket.returnValue=malloc(strlen(resultbuf) + 1); strcpy(datapacket.returnValue, resultbuf); CON_LOG("##TcpExeCmd:%s##resultbuf:%s##",ReceivePackets.returnValue, datapacket.returnValue); ret = WriteServer(); break; default: sleep(5); CON_LOG("NO CONNECT"); break; } CON_LOG("==="); return ret; }这段程序可行性和优化
这段程序的可行性是可以的,它实现了一个服务器与客户端之间的通信。根据代码逻辑,服务器接收数据包并根据选择的类型进行相应的操作,然后将数据包发送回客户端。
在优化方面,我有几点建议:
1. 对于内存分配和释放,建议在使用完之后立即释放,避免出现内存泄漏。可以在每次使用完后调用相应的free函数来释放内存。
2. 在读取数据时,可以考虑使用非阻塞IO(non-blocking I/O)来提高程序的性能和响应速度。
3. 在处理switch语句时,可以添加一个default选项来处理未知的选择类型,以防止程序出现意外情况。
4. 在使用system函数执行命令时,建议使用更安全的方式,比如使用exec系列函数来执行命令。
5. 对于错误处理,可以考虑添加适当的错误处理代码,例如对write函数返回值进行判断并处理错误情况。
6. 对于网络通信部分,可以考虑添加异常处理代码,以应对网络中断或连接超时等情况。
这些只是一些建议,具体优化还需要根据实际需求和场景进行。希望对你有帮助!如果有任何问题,请随时提问。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![application/msword](https://img-home.csdnimg.cn/images/20210720083327.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)