gpt4 book ai didi

c++ - 使套接字服务器接受多个客户端

转载 作者:可可西里 更新时间:2023-11-01 10:08:21 26 4
gpt4 key购买 nike

我想更改 socket class我正在接受无限数量的客户。目前它允许一个客户端,一旦该客户端断开连接,服务器就会退出。

#include "stdafx.h"

#include "mySocket.h"
#include "myException.h"
#include "myHostInfo.h"

void main()
{

#ifdef WINDOWS_XP
// Initialize the winsock library
WSADATA wsaData;
try
{
if (WSAStartup(0x101, &wsaData))
{
myException* initializationException = new myException(0,"Error: calling WSAStartup()");
throw initializationException;
}
}
catch(myException* excp)
{
excp->response();
delete excp;
exit(1);
}
#endif

// get local server information
myHostInfo uHostAddress;
string localHostName = uHostAddress.getHostName();
string localHostAddr = uHostAddress.getHostIPAddress();
cout << "------------------------------------------------------" << endl;
cout << " My local host information:" << endl;
cout << " Name: " << localHostName << endl;
cout << " Address: " << localHostAddr << endl;
cout << "------------------------------------------------------" << endl;

// open socket on the local host
myTcpSocket myServer(PORTNUM);
cout << myServer;

myServer.bindSocket();
cout << endl << "server finishes binding process... " << endl;

myServer.listenToClient();
cout << "server is listening to the port ... " << endl;

// wait to accept a client connection.
// processing is suspended until the client connects
cout << "server is waiting for client connecction ... " << endl;

myTcpSocket* client; // connection dedicated for client communication
string clientHost; // client name etc.
client = myServer.acceptClient(clientHost);

cout << endl << "==> A client from [" << clientHost << "] is connected!" << endl << endl;

while(1)
{
//Send message to the client
client->sendMessage(std::string("Test"));

// receive from the client
string clientMessageIn = "";
int numBytes = client->recieveMessage(clientMessageIn); //Get message from client, non-blocking using select()
if ( numBytes == -99 ) break;

if(clientMessageIn != "")
{
std::cout << "received: " << clientMessageIn << std::endl; //What did we receive?

/* Do somethign with message received here */
}
}

#ifdef WINDOWS_XP
// Close the winsock library

try
{
if (WSACleanup())
{
myException* cleanupException = new myException(0,"Error: calling WSACleanup()");
throw cleanupException;
}
}
catch(myException* excp)
{
excp->response();
delete excp;
exit(1);
}

#endif
}

我如何更改 main() 函数,使其不断等待新客户端连接,一旦它们连接,就为他(客户端)创建一个新线程,或一个新的处理程序套接字(无论是什么) ).

我确实找到了 this thread 提供了信息,但我缺乏在上面的代码中实际实现它所需的套接字知识。

答案是当进行套接字通信时,您基本上有一个用于所有传入连接的监听器套接字,以及用于每个连接的客户端的多个处理程序套接字。

所以我在猜测我的代码;

myTcpSocket myServer(PORTNUM);
myServer.bindSocket();
myServer.listenToClient();

将是监听器套接字

但是我应该在哪里/如何将正在连接到 handler socket 的客户端 fork 出来?

很抱歉我没能表现出更多的努力,我不喜欢给人留下懒惰的印象。但是对于我搜索的所有时间以及由此产生的反复试验,我没有太多可以展示的东西。

最佳答案

这个想法很简单,您只需等待传入的连接,一旦接受,就将套接字传递给线程。

需要将accept返回的新socket传递给新线程;您可以每次都生成一个新线程并通过参数传递套接字,或者将套接字添加到一组工作线程使用的共享队列中。

这是我编写的一个简单代理的一些代码,它对线程使用 boost 并围绕套接字函数使用一个简单的 OOP 包装器。

主线程 - 它创建 4 个空闲等待的工作线程要发出信号的信号量。它将所有接受的连接推送到全局队列:

// Global variables

const size_t MAX_THREADS = 4;

queue<Socket> socketBuffer; // Holds new accepted sockets
boost::mutex queueGuard; // Guards the socketBuffer queue
semaphore queueIndicator; // Signals a new connection to the worker threads
bool ctrlc_pressed = false;

// Inside the main function...

boost::thread_group threads;
for(int i = 0; i < MAX_THREADS; i++)
{
threads.create_thread(boost::bind(&threadHandleRequest, i+1));
}

while(!ctrlc_pressed)
{
// wait for incoming connections and pass them to the worker threads
Socket s_connection = s_server.accept();
if(s_connection.valid())
{
boost::unique_lock<boost::mutex> lock(queueGuard);
socketBuffer.push(s_connection);
queueIndicator.signal();
}
}

threads.interrupt_all(); // interrupt the threads (at queueGuard.wait())
threads.join_all(); // wait for all threads to finish

s_server.close();

线程代码:

bool threadHandleRequest(int tid)
{
while(true)
{
// wait for a semaphore counter > 0 and automatically decrease the counter
try
{
queueIndicator.wait();
}
catch (boost::thread_interrupted)
{
return false;
}

boost::unique_lock<boost::mutex> lock(queueGuard);

assert(!socketBuffer.empty());

Socket s_client = socketBuffer.front();
socketBuffer.pop();

lock.unlock();

// Do whatever you need to do with the socket here
}
}

希望对您有所帮助:)

关于c++ - 使套接字服务器接受多个客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8526478/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com