Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.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+中将多个客户端连接到单个服务器+;在Windows-visualstudio上? 我用C++编写了服务器程序,C++中也有客户端程序。 两者都可以正常工作,但如果一个客户端与服务器通信,则另一个客户端无法连接到同一服务器。如果假设当我关闭客户端1时,我的第二个客户端也无法连接到服务器。我用多个线程启动了服务器,以连接多个客户端,但只有一个客户端正在连接_C++_Multithreading_Sockets - Fatal编程技术网

如何在c+中将多个客户端连接到单个服务器+;在Windows-visualstudio上? 我用C++编写了服务器程序,C++中也有客户端程序。 两者都可以正常工作,但如果一个客户端与服务器通信,则另一个客户端无法连接到同一服务器。如果假设当我关闭客户端1时,我的第二个客户端也无法连接到服务器。我用多个线程启动了服务器,以连接多个客户端,但只有一个客户端正在连接

如何在c+中将多个客户端连接到单个服务器+;在Windows-visualstudio上? 我用C++编写了服务器程序,C++中也有客户端程序。 两者都可以正常工作,但如果一个客户端与服务器通信,则另一个客户端无法连接到同一服务器。如果假设当我关闭客户端1时,我的第二个客户端也无法连接到服务器。我用多个线程启动了服务器,以连接多个客户端,但只有一个客户端正在连接,c++,multithreading,sockets,C++,Multithreading,Sockets,我的服务器程序: #include <iostream> #include <winsock2.h> #include <Windows.h> #include <process.h> #include <thread> #pragma comment(lib,"ws2_32.lib") static const int num_of_threads = 2; void client_disconnected(SOCKET Sock

我的服务器程序:

#include <iostream>
#include <winsock2.h>
#include <Windows.h>
#include <process.h>
#include <thread>
#pragma comment(lib,"ws2_32.lib")

static const int num_of_threads = 2;

void client_disconnected(SOCKET Socket);

void start_server()
{
    WSADATA WsaDat;
    if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)
    {
        std::cout<<"WSA Initialization failed!\r\n";
        WSACleanup();
        system("PAUSE");
    }

    SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(Socket==INVALID_SOCKET)
    {
        std::cout<<"Socket creation failed.\r\n";
        WSACleanup();
        system("PAUSE");
    }

    SOCKADDR_IN serverInf;
    serverInf.sin_family=AF_INET;
    serverInf.sin_addr.s_addr=INADDR_ANY;
    serverInf.sin_port=htons(8888);

    if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serverInf))==SOCKET_ERROR)
    {
        std::cout<<"Unable to bind socket!\r\n";
        WSACleanup();
        system("PAUSE");
    }

    listen(Socket,3);

    SOCKET TempSock=SOCKET_ERROR;
    while(TempSock==SOCKET_ERROR)
    {
        std::cout<<"Waiting for incoming connections...\r\n";
        Sleep(5000);    
        TempSock=accept(Socket,NULL,NULL);
    }

    // If iMode!=0, non-blocking mode is enabled.
    u_long iMode=1;
    ioctlsocket(Socket,FIONBIO,&iMode);

    Socket=TempSock;
    std::cout<<"Client connected!\r\n\r\n";

    // Main loop
    for(;;)
    {
        int nError=WSAGetLastError();
        if(nError!=WSAEWOULDBLOCK&&nError!=0)
        {
            client_disconnected(Socket);
            break;
        }
        char *szMessage="Welcome to the server!\r\n";
        send(Socket,szMessage,strlen(szMessage),0);
        Sleep(2000);            
    }
}
void client_disconnected(SOCKET Socket)
{
    std::cout<<"Client disconnected!\r\n";

    // Shutdown our socket
    shutdown(Socket,SD_SEND);

    // Close our socket entirely
    closesocket(Socket);

    WSACleanup();
}


int main()
{
   //starting multiple threads for invoking server

    std::thread threads[num_of_threads];
    //This statement will launch multiple threads in loop
    for (int i = 0; i < num_of_threads; ++i) {
        threads[i] = std::thread(start_server);
        Sleep(2000);
    }

    for (int i = 0; i < num_of_threads; ++i) {
        threads[i].join();
    }
    return 0;

}
#include <iostream>
#include <winsock2.h>
#include <Windows.h>
#include <process.h>
#include "client.h"
#pragma comment(lib,"ws2_32.lib") 


void MultipleClient :: receiveToClient(void*data)
{
    WSADATA WsaDat;
    if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)
    {
        std::cout<<"Winsock error - Winsock initialization failed\r\n";
        WSACleanup();
        system("PAUSE");

    }

    // Create our socket

    SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(Socket==INVALID_SOCKET)
    {
        std::cout<<"Winsock error - Socket creation Failed!\r\n";
        WSACleanup();
        system("PAUSE");

    }

    // Resolve IP address for hostname
    struct hostent *host;
    if((host=gethostbyname("localhost"))==NULL)
    {
        std::cout<<"Failed to resolve hostname.\r\n";
        WSACleanup();
        system("PAUSE");

    }

    // Setup our socket address structure
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port=htons(8888);
    SockAddr.sin_family=AF_INET;
    SockAddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);

    // Attempt to connect to server
    if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr))!=0)
    {
        std::cout<<"Failed to establish connection with server\r\n";
        WSACleanup();
        system("PAUSE");

    }

    // If iMode!=0, non-blocking mode is enabled.
    u_long iMode=1;
    ioctlsocket(Socket,FIONBIO,&iMode);

    // Main loop
    for(;;)
    {
        // Display message from server
        char buffer[1000];
        memset(buffer,0,999);
        int inDataLength=recv(Socket,buffer,1000,0);
        std::cout<<buffer;

        //end client when server is disconnected
        int nError=WSAGetLastError();
        if(nError!=WSAEWOULDBLOCK&&nError!=0)
        {
            std::cout<<"Winsock error code: "<<nError<<"\r\n";
            std::cout<<"Server disconnected!\r\n";
            // Shutdown our socket
            shutdown(Socket,SD_SEND);

            // Close our socket entirely
            closesocket(Socket);

            break;
        }
        Sleep(2000);
    }

    WSACleanup();
    system("PAUSE");

}

class Client{
        public:
    static unsigned int __stdcall receiveMessageThread(void *p_this)
        {
            MultipleClient* mc = static_cast<MultipleClient*>(p_this);
            mc-> receiveToClient(p_this); // Non-static member function!
            return 0;
        }
    void startThread()
    {
        HANDLE myhandleA;
            myhandleA = (HANDLE)_beginthreadex(0,0,&Client::receiveMessageThread,this,0, 0);
            WaitForSingleObject(myhandleA, INFINITE);
    }
    };
    int main(void)
    {

        Client *c = new Client;
        c->startThread();

        return 0;
    }
#包括
#包括
#包括
#包括
#包括
#pragma注释(lib,“ws2_32.lib”)
线程的静态常量int num=2;
无效客户端_已断开连接(套接字);
无效启动\u服务器()
{
WSADATA WsaDat;
if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)
{

std::cout您在线程之间分配工作的方式是错误的

您希望一个线程打开侦听套接字并在那里等待传入连接。请注意,每个端口不能有多个侦听套接字,因此您肯定不希望多个线程同时尝试侦听同一端口

如果连接进入,
accept
将为您提供一个新的套接字对象。您仍然有原始的侦听套接字,它等待新的连接,但您现在还有第二个套接字,它已经与客户端建立了连接

现在您可以拆分工作:让一个线程返回到调用原始套接字上的
listen
,等待新连接,而另一个线程抓住新套接字并执行必要的I/O以与客户端交互


在这个简单的方案中,每个客户端连接总是有一个线程,另外还有一个用于侦听套接字的线程。由于所有这些线程都将花费大量时间等待网络I/O完成,因此您可以使用异步I/O在更少的线程(甚至单个线程)之间共享工作负载线程,但这稍微复杂一些,所以我建议您将其留作第二稿。

使用线程。套接字服务器使用一个线程来接受来自客户端的所有请求连接

每个线程都有由方法accept分配的套接字,如下所示:

服务器。此方法(
运行
)在新线程下运行。我不认为该方法是实用的,但请记住,此方法将创建新线程,该线程将参与远程端点

void SocketServer::run()
{
    int err = 0;

    err = initSocketServer();

    //Fallo el inicio de socket server.
    if (err != NO_ERROR)
    {
        stringstream out;
        out << "There was a problem to bind Native Port: " << _port;
        log->writeError(out.str());
        bKeepRunning = false;
    }
    else
        bKeepRunning = true;

    stringstream out;
    out << "Native Port stablished on port: " << _port;
    log->writeInfo(out.str());


    while (bKeepRunning)
    {
        stringstream out;
        SOCKET socket;

        socket = accept(server, NULL,NULL);

        if (bKeepRunning)
        {
            bool reuseadd = true;
            bool keepAlive = true;

            setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseadd, sizeof(bool));
            setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (const char*)&keepAlive, sizeof(bool));


            //This method will create a new Thread wihc recives the socket.
            connectionRequest(socket);


            // It is ready to accept the nexto connection...
        }
    }

    serverStoped();
}
void SocketServer::run()
{
int err=0;
err=initSocketServer();
//Fallo el inicio de socket服务器。
如果(错误!=无错误)
{
流出来;
出来
void SocketClient::run()
{
    stringstream out;
    bKeepRunning = true;
    bool wasClosed = false;
    int error = 0;
    error = 0;
    do
    {
        if(bSocketSet)
            log->writeDebug(_dlevel,"Socket Previamente asignado, No hay conexion");
        else
            log->writeDebug(_dlevel, "SIN Socket Previamente asignado, Se conectara");

        if(!bSocketSet) //If the socket has not been set
            bConnected = openConnection();

        if (bConnected)
        {

            if (!bSocketSet) //If the socket has not been set
            {
                out.str("");
                out.clear();
                out << "Connected to Server [" << _host << ":" << _port << "]";
                log->writeInfo(out.str());
            }

            //The readMessage will performed a loop to read data an report.
            error = readMessage(&wasClosed);

            if ((error != 0 && bKeepRunning) || wasClosed)
            {
                out.str("");
                out.clear();
                out << "There was an error on reading data. The connection colud be closed.";
                log->writeError(out.str());
                //if(!wasClosed)
                //closeConnection();
                bConnected = false;
            }

        } // if (bConnected) 
        else 
        {
            if (!bSocketSet)
            {
                out.str("");
                out.clear();
                out << "It was not possible to connect to Server [" << _host << ":" << _port << "]";
                log->writeError(out.str());
                waitForResume(15000); //Wait for 15 second to try to reconect
            }
        } //Else Not Connected

    } while (bKeepRunning && !bSocketSet); //do while The socket is not a Socket set by SocketServer

    if (bConnected)
        closeConnection();
}//SocketClient::run()