Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于套接字的事件循环_C++_Sockets_Unix_Event Loop - Fatal编程技术网

C++ 基于套接字的事件循环

C++ 基于套接字的事件循环,c++,sockets,unix,event-loop,C++,Sockets,Unix,Event Loop,我想设置基于套接字的服务器-客户端通信。客户端可以连接到服务器并从中接收不同的通知。这可以在客户端实现,如下所示 ... Message* msg = NULL; while ( msg = receiveMessage() ) handleMessage( msg ); ... 此代码将在客户端的独立线程中运行,并应处理来自服务器的不同类型的通知。但客户端也应该能够通过发送请求与套接字通信,即 Request requestMsg; if ( sendMessage( request

我想设置基于套接字的服务器-客户端通信。客户端可以连接到服务器并从中接收不同的通知。这可以在客户端实现,如下所示

...
Message* msg = NULL;
while ( msg = receiveMessage() )
    handleMessage( msg );
...
此代码将在客户端的独立线程中运行,并应处理来自服务器的不同类型的通知。但客户端也应该能够通过发送请求与套接字通信,即

Request requestMsg;
if ( sendMessage( requestMsg ) )
{
    Message* response = receiveMessage();
    if ( response->type() == REQUEST_REPLY )
    ...
}

问题:如何实现这一点?我不想中断阅读线程,但我应该收到对特定请求的响应。这是基于本地域流的unix套接字。

..::下面是ASCII代码:

如果你讨厌艺术,就到此为止

下面的示意图不会阻塞服务器或客户端。
许多MMORPG使用此功能来保护连接,并使协议更难破解

     [================ ~~ Server ~~ ================]
     [ Select / Poll ]*4             5*[ Dispatcher ]
        ||      /\                             ||
        ||      ||                             ||
     *1 ||      ||2*                         *3||
        ||      ||                             ||
        \/      ||                             \/
     [ Thread 1 Basic IO ]       [ Thread 2 Listener]
     [=============== ~~ Client ~~ =================]

 *1 // send
 *2 // recv

 *3 // bind listen accept recv OR they will communicate using UDP
    // to a different port

 *4 // the server will process the clients normally
    // using select / poll / epoll / kqueue / `/dev/poll`

 *5 // The client will either setup a temporary server to process
    // the servers opcodes
 OR
    // It will accept UDP packets using recvfrom()

 *5 // I'd recommend using UDP so that the server can loop through the existing
    // connections and sendto() the opcodes which will be provided via a message
    // queue.

…::下面的ASCII内容::

如果你讨厌艺术,就到此为止

下面的示意图不会阻塞服务器或客户端。
许多MMORPG使用此功能来保护连接,并使协议更难破解

     [================ ~~ Server ~~ ================]
     [ Select / Poll ]*4             5*[ Dispatcher ]
        ||      /\                             ||
        ||      ||                             ||
     *1 ||      ||2*                         *3||
        ||      ||                             ||
        \/      ||                             \/
     [ Thread 1 Basic IO ]       [ Thread 2 Listener]
     [=============== ~~ Client ~~ =================]

 *1 // send
 *2 // recv

 *3 // bind listen accept recv OR they will communicate using UDP
    // to a different port

 *4 // the server will process the clients normally
    // using select / poll / epoll / kqueue / `/dev/poll`

 *5 // The client will either setup a temporary server to process
    // the servers opcodes
 OR
    // It will accept UDP packets using recvfrom()

 *5 // I'd recommend using UDP so that the server can loop through the existing
    // connections and sendto() the opcodes which will be provided via a message
    // queue.

在客户端的接收方线程中,应该使用线程安全对象来推送和弹出消息。如果你有一个C++ 11编译器,你可以考虑<代码> STD::vector < /C>。下面是一个线程安全对象的简单实现,它可能适合您的需要

class MessageQueue
{
public:
  typedef std::shared_ptr<Message> SpMessage;

  bool empty() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return messages_.empty();
  }

  SpMessage pop() {
    std::lock_guard<std::mutex> lock(mutex_);
    SpMessage msg(messages_.front());
    messages_.pop_front();
    return msg;
  }

  void push(SpMessage const& msg)
    std::lock_guard<std::mutex> lock(mutex_);
    messages_.push_back(msg);
  }

private:
  MessageQueue(const MessageQueue&);  // disable 
  MessageQueue& operator=(const MessageQueue&);  // disable
  std::vector<SpMessage> messages_;
  std::mutex mutex_;
};

typedef std::shared_ptr<MessageQueue> SpMessageQueue;
class消息队列
{
公众:
typedef std::共享的\u ptr SpMessage;
bool empty()常量{
std::锁\保护锁(互斥锁);
返回消息_u3;.empty();
}
SpMessage pop(){
std::锁\保护锁(互斥锁);
SpMessage msg(messages_u.front());
消息u.pop_front();
返回味精;
}
无效推送(SpMessage const&msg)
std::锁\保护锁(互斥锁);
消息推回(msg);
}
私人:
MessageQueue(const MessageQueue&);//使残废
MessageQueue&运算符=(const MessageQueue&);//使残废
std::向量消息;
std::mutex mutex;
};
typedef std::shared_ptr SpMessageQueue;
此时,您有了一个可共享的线程安全队列。在主线程和套接字线程之间共享此队列。如果希望发送也在单独的线程上,也可以使用两个线程,例如,从一个消息队列弹出消息,处理它,并在另一个队列上排队响应

您可以在服务器上使用同样的东西

message类应该能够存储一个
std::vector
,这样您就可以通过套接字发送/接收普通的旧数据,并将其装入和取出
消息进行处理


如果您需要有关启动线程的帮助,请查看本教程

在客户端的接收方线程中,应该使用线程安全对象来推送和弹出消息。如果你有一个C++ 11编译器,你可以考虑<代码> STD::vector < /C>。下面是一个线程安全对象的简单实现,它可能适合您的需要

class MessageQueue
{
public:
  typedef std::shared_ptr<Message> SpMessage;

  bool empty() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return messages_.empty();
  }

  SpMessage pop() {
    std::lock_guard<std::mutex> lock(mutex_);
    SpMessage msg(messages_.front());
    messages_.pop_front();
    return msg;
  }

  void push(SpMessage const& msg)
    std::lock_guard<std::mutex> lock(mutex_);
    messages_.push_back(msg);
  }

private:
  MessageQueue(const MessageQueue&);  // disable 
  MessageQueue& operator=(const MessageQueue&);  // disable
  std::vector<SpMessage> messages_;
  std::mutex mutex_;
};

typedef std::shared_ptr<MessageQueue> SpMessageQueue;
class消息队列
{
公众:
typedef std::共享的\u ptr SpMessage;
bool empty()常量{
std::锁\保护锁(互斥锁);
返回消息_u3;.empty();
}
SpMessage pop(){
std::锁\保护锁(互斥锁);
SpMessage msg(messages_u.front());
消息u.pop_front();
返回味精;
}
无效推送(SpMessage const&msg)
std::锁\保护锁(互斥锁);
消息推回(msg);
}
私人:
MessageQueue(const MessageQueue&);//使残废
MessageQueue&运算符=(const MessageQueue&);//使残废
std::向量消息;
std::mutex mutex;
};
typedef std::sharedptr SpMessageQueue;
此时,您有了一个可共享的线程安全队列。在主线程和套接字线程之间共享此队列。如果希望发送也在单独的线程上,也可以使用两个线程,例如,从一个消息队列弹出消息,处理它,并在另一个队列上排队响应

您可以在服务器上使用同样的东西

message类应该能够存储一个
std::vector
,这样您就可以通过套接字发送/接收普通的旧数据,并将其装入和取出
消息进行处理


如果您需要有关启动线程的帮助,请查看本教程

是否可以提供使用此MessageQueue类的完整示例?是否可以提供使用此MessageQueue类的完整示例?