C ++套接字-服务器不接受多个客户端(Linux) [英] C++ Sockets - Server doesn't accept multiple clients (linux)

查看:56
本文介绍了C ++套接字-服务器不接受多个客户端(Linux)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有可用的服务器和客户端代码.服务器和客户端可以正确连接并彼此聊天.但是,当我打开另一个客户终端时,客户说的是Awaiting confirmation from the server,什么也没有.尽管服务器和客户端#1仍然可以聊天.

I have working server and client code. The server and client can connect and chat with each other correctly. But when I open another client terminal, the client is says Awaiting confirmation from the server and nothing else. Although server and client #1 can still chat.

我搜索了多线程,但是它们显示的示例或代码段是高级的.也许稍作解释或举个例子会很有帮助!

I searched on multi-threading but the examples or code snippets they show is advanced. Maybe a little explanation or an example will help a lot!

下面的代码正在工作.我有一台正在运行的服务器,但它仅接受一个连接.如何使服务器允许多个连接?这样我就可以使该程序看起来像群聊.

The code below is working. I have a working server but it only accepts one connection. How do I make the server to allow multiple connection? So that I can make the program look like a group chat.

client.cpp(当2号客户端连接时,代码将在第40行冻结)

client.cpp (when client #2 connects, the code freezes at line 40)

#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;

int main()
{
    char a;
    int client;
    int portNum = 1500;
    int bufsize = 1024;
    char* buffer = new char[bufsize];
    bool isExit = false;
    char* ip = "127.0.0.1";

    struct sockaddr_in direc;

    if ((client = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        cout << "\nError creating socket..." << endl;
        exit(0);
    }

    cout << "\nSocket created successfully..." << endl;
    direc.sin_family = AF_INET;
    direc.sin_port = htons(portNum);
    inet_pton(AF_INET, ip, &direc.sin_addr);

    if (connect(client,(struct sockaddr *)&direc, sizeof(direc)) == 0)
        cout << "Connection to the server " << inet_ntoa(direc.sin_addr) << endl;

    cout << "Awaiting confirmation from the server..." << endl; //line 40
    recv(client, buffer, bufsize, 0);

    cout << "\n=> Enter # to terminate the connection\n" << endl;

    do {
        cout << "Client: ";
        do {
            cin >> buffer;
            send(client, buffer, bufsize, 0);
            if (*buffer == '#') {
                send(client, buffer, bufsize, 0);
                *buffer = '*';
                isExit = true;
            }
        } while (*buffer != 42);

        cout << "Server: ";
        do {
            recv(client, buffer, bufsize, 0);
            cout << buffer << " ";
            if (*buffer == '#') {
                *buffer = '*';
                isExit = true;
            }

        } while (*buffer != 42);
        cout << endl;

    } while (!isExit);
    cout << "=> Connection terminated.\nGoodbye";

    close(client);
    return 0;
}

server.cpp

server.cpp

#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;

int main()
{
    int client, server;
    int bufsize = 1024;
    int portNum = 1500;
    bool isExit = false;
    char* buffer = new char[bufsize];

    struct sockaddr_in direc;
    socklen_t tamano;
    pid_t pid;

    if ((client = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        cout << "\nError establishing socket..." << endl;
        exit(1);
    }

    cout << "\nSocket server has been created..." << endl;

    direc.sin_family = AF_INET;
    direc.sin_addr.s_addr = htons(INADDR_ANY);
    direc.sin_port = htons(portNum);

    if ((bind(client, (struct sockaddr*)&direc,sizeof(direc))) < 0) {
        cout << "\nError binding connection..." << endl;
        return -1;
    }

    tamano = sizeof(direc);
    cout << "Looking for clients..." << endl;
    listen(client, 1);

    while ((server = accept(client,(struct sockaddr *)&direc,&tamano)) > 0) {
        strcpy(buffer, "Server connected...\n");
        send(server, buffer, bufsize, 0);
        cout << "Connected with the client, you are good to go..." << endl;
        cout << "Enter # to end the connection\n" << endl;

        cout << "Client: ";
        do {
            recv(server, buffer, bufsize, 0);
            cout << buffer << " ";
            if (*buffer == '#') {
                *buffer = '*';
                isExit = true;
            }
        } while (*buffer != '*');

        do {
            cout << "\nServer: ";
            do {
                cin >> buffer;
                send(server, buffer, bufsize, 0);
                if (*buffer == '#') {
                    send(server, buffer, bufsize, 0);
                    *buffer = '*';
                    isExit = true;
                }
            } while (*buffer != '*');

            cout << "Client: ";
            do {
                recv(server, buffer, bufsize, 0);
                cout << buffer << " ";
                if (*buffer == '#') {
                    *buffer == '*';
                    isExit = true;
                }
            } while (*buffer != '*');
        } while (!isExit);

        cout << "\n=> Connection terminated... " << inet_ntoa(direc.sin_addr);
        close(server);
        cout << "\nGoodbye..." << endl;
        isExit = false;
    }

    close(client);
    return 0;
}

如何使服务器接受多个连接?

How do I make the server accept multiple connection?

谢谢!

推荐答案

为了正确地支持多个连接,您应该为每个传入的连接启动一个新线程.每个新连接由accept()返回的其自己的唯一套接字描述符标识.一个简单的例子:

In order to properly support multiple connections you should fire up a new thread for each incoming connection. Each new connection is identified by its own unique socket descriptor returned by accept(). A simple example:

while ((accepted = accept(client,(struct sockaddr *)&direc,&tamano)) > 0) {
    /*Create the thread and pass the socket descriptor*/
    if( pthread_create(new_thread, &thread_attributes, &handle_tcp_connection, (void *)accepted) != 0){
      perror("create thread");
      exit(EXIT_FAILURE);
    }
}

这篇关于C ++套接字-服务器不接受多个客户端(Linux)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆