Ace*_*ohn 1 c++ sockets function cin
我目前正在研究套接字程序.
是否可以像下面的用例一样使用流插入运算符?
__sin >> var; // similar to cin >> var;
Run Code Online (Sandbox Code Playgroud)
功能的主体是什么样的
var = remoteConsole.getline();
Run Code Online (Sandbox Code Playgroud)
所以当我使用我的远程控制台时,我可以使用该功能代替cin,在远程位置,我知道我可以使用类似的东西
cin.getLine() 要么 var= remoteConsole.cin()
但我试图避免这种情况.
我开始认为我试图做的事情虽然看起来很容易,但我可能不得不抛弃这个想法.我已经好好看了一下,但我尝试的一切都充满了编译错误.任何帮助,将不胜感激.谢谢
编辑
对于那些不清楚我在谈论什么的人(我试图清楚地解释)我试图用与cin相同的语法创建一个函数,而不是从控制台获取输入,从其他地方获取它,即一个插座.我在创建一个使用<<或>>而不是(和)的函数时遇到了麻烦.我希望语法与cin >>和cout <<相同.我的问题应该是,我从哪里开始这样做?
我找到了一种方法来做到这一点,但我不知道它会有多安全.我创建了两个结构,并在另一个中重载了<< in one和>>
struct out_t {
template<typename T>
out_t& operator << (T&& x) {
// Send x to the socket
// Use console for now
cout << x;
return *this;
}
};
out_t socout;
struct in_t {
template<typename T>
in_t& operator >> (T&& x) {
// get x from the socket and wait untill done so;
// Use console for now
cin >> x;
return *this;
}
};
in_t socin;
Run Code Online (Sandbox Code Playgroud)
所以现在我可以使用
socout << "Some message"; // which i can now send to an external console
socin >> strValue;// i can request the data needed from external program/computer
Run Code Online (Sandbox Code Playgroud)
对不起,如果我没有开始解释这个.可能还有改进的余地,但我对此非常满意.如果不是这样的话,请有人请告诉我正确的方法.
谢谢大家;
如果您只想创建一个std::istream&从套接字而不是预定义流中读取的内容,则可以创建一个自定义std::streambuf:它std::istream实际上不会执行任何字符读取.这是流缓冲区的工作.所有这些std::istream都提供了一个过载输入操作,保持格式标志,错误指示器和流缓冲区的接口.
要创建用于输入字符的自定义流缓冲区,您需要覆盖underflow()以将字符读入缓冲区,例如,类似这样的东西(使用典型的UNIX API作为套接字;在不同的系统上,只是访问套接字的代码确实不同):
class socketbuf: public std::streambuf {
typedef std::streambuf::traits_type traits_type;
int d_fd;
char d_buffer[2000];
int underflow() {
if (this->gptr() == this->egptr()) {
std::streamsize size = ::read(this->d_fd, this->d_buffer, sizeof(this->d_buffer));
this->setg(this->d_buffer, this->d_buffer, this->d_buffer + size);
}
return this->gptr() == this->egptr()
? traits_type::eof()
: traits_type::to_int_type(*this->gptr());
}
public:
socketbuf(int fd): d_fd(fd) {}
};
Run Code Online (Sandbox Code Playgroud)
一旦你有这样的流缓冲区,你可以std::istream用指向这个流缓冲区的指针初始化一个.如果您计划多次使用此设置,则可能需要创建一个自定义isocketstream类,该类创建流缓冲区并std::istream使用结果设置.这里只是拆包使用:
int fd = get_and_setup_socket(); // get a file descriptor for the socket somehow
socketbuf sbuf(fd);
std::istream sin(&sbuf);
std::istream& in(use_local? std::cin: sin);
if (in >> whatever) {
std::cout << "received '" << whatever << "'\n";
}
Run Code Online (Sandbox Code Playgroud)
您可能希望使用输出操作来补充输入操作.为此,您还将覆盖在overflow()设置缓冲区溢出时调用的函数,以及sync()在流刷新时调用的函数.