c++ - 如何正确实现 select 以正确从 stdin 和 recv() 获取数据
问题描述
这是我的问题的延续:我在 C++ 中对 netcat 的尝试不会让我从服务器得到回复,以便更好地了解我推荐阅读的情况。据我了解,问题在于程序可以从标准输入获取数据,也可以同时从两者获取getline()
数据recv()
。所以我需要使用select()
检查状态recv()
来查看是否有任何数据要输出。我一直在研究 Unix 文件描述符并使用它,select()
但是我似乎不太了解,或者至少我不知道如何将这些示例应用到我的程序中。那么,我怎样才能正确地调用select()
我的代码以便正确地从中获取数据recv()
呢?
我的代码:
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <stdlib.h>
#include <errno.h>
using namespace std;
int main (int argc, char** argv) {
if (argv[1] == NULL) {
cout << "\033[31mTARGET NOT SPECIFIED - TERMINATING...\033[0m\n";
return -1;
}
if (argv[2] == NULL) {
cout << "\033[31mPORT NOT SPECIFIED - TERMINATING...\033[0m\n";
return -2;
}
string target = argv[1];
int port = atoi(argv[2]);
cout << "GENERATING SOCKET...\n";
int chatter = socket(AF_INET, SOCK_STREAM, 0);
if (chatter == -1) {
cout << "\033[31mSOCKET GENERATION FAILURE - TERMINATING...\033[0m\n";
return -3;
}
cout << "\033[32mSUCCESSFULLY GENERATED SOCKET\033[0m\n";
struct sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, target.c_str(), &hint.sin_addr);
cout << "CONNECTING TO " << target << " AT PORT " << port << "...\n";
int connection_status = connect(chatter, (sockaddr*)&hint, sizeof(hint));
if (connection_status == -1) {
cout << "\033[31mCONNECTION FAILURE - TERMINATING...\033[0m\n";
return -4;
}
cout << "\033[32mCONNECTED TO HOST\033[0m\n";
char buf[4096] = {0};
string msg;
while (true) {
getline(cin, msg);
msg+"\r\n";
int sendmsg = send(chatter, msg.c_str(), msg.size()+1, 0);
if (sendmsg == -1) {
cout << "\033[31mMESSAGE SENDING FAILURE - TERMINATING...\033[0m\n";
return -5;
}
int byterecv = recv(chatter, buf, 4096, 0);
if (byterecv == -1) {
cout << "\033[31mFAILURE TO RECEIVE MESSAGE - TERMINATING...\033[0m\n";
return -6;
}
cout << byterecv << "\n";
cout << buf << "\n";
}
close(chatter);
return 0;
}
虽然我需要帮助来修复程序,但我也认为了解 select 将如何用于它将有助于教会我关于它以及如何在将来使用它。
解决方案
推荐阅读
- c# - ConcurrentDictionary: Proper small initial capacity
- django - 禁止保存到数据库(Django)的模型实例超过 1 个?
- spring-boot - How to update data on Principal object on Spring Boot
- beautifulsoup - 删除 beautifulSoup 输出中 {} 括号之间的所有内容
- .net - How do I restore Nuget Packages from a private NugetFeed in a devcontainer on Windows?
- node.js - Nodejs、GraphQl 和 SQLServer 返回空值
- mqtt - NodeRED: Configuration lost after modifying flows.json
- javascript - mtlLoader 模块“不提供名为 'MTLLoader' 的导出错误
- sql-server - k8s 与 SQL 服务器的秘密轮换
- javascript - IE 11 fullpage.js 锚问题