E
E
Evgeny Petryaev2020-08-21 17:36:33
C++ / C#
Evgeny Petryaev, 2020-08-21 17:36:33

Why doesn't the server program give the following connections?

I start the server designed for one client after it is disconnected, another client is connected, but there is no reaction from the second client, but not always.
Server:

// ServerOne.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//

#include <iostream>
#include <WinSock.h>
#pragma comment (lib,"WS2_32.lib")
void error(const char* msg)
{
    //perror(msg);
    std::cout<<'\n'<<WSAGetLastError();
    WSACleanup();
    std::cin.ignore();
    exit(1);
}
void bzero(char*buf, int l)
{
    for (int i = 0; i < l; i++)
        buf[i] = '\0';
}
struct arg_s
{
    char* buffer;
    bool exit;
};
struct arg_sa
{
    struct arg_s* lalk;
    int current;
};
#define type struct arg_sa
int sockfd, * newsockfd; 
int buflen = 100000;
struct sockaddr_in *cli_addr;
int* clilen;
int currentclient;

void session_(LPVOID args)
{
    int current = currentclient++;
    bzero((char*)&(cli_addr[current]), sizeof(&(cli_addr[current])));
    newsockfd[current] = accept(sockfd, (struct sockaddr*)&(cli_addr[current]), &(clilen[current]));
    if (newsockfd[current] < 0)
    {
        error("Error on accept\n");
    }
    int n = recv(newsockfd[current], ((type*)args)[current].lalk->buffer
    , buflen, 0);
    std::cout << "data receving " << ((type*)args)[current].current << std::endl;
    if (n < 0)
        error("ERROR reading from socket");
    system(((type*)args)[current].lalk->buffer);
    std::cout << "data end " << std::endl;
    FILE* f;
    fopen_s(&f,"1.txt", "r");
    int countfile = 0;
    while ((((type*)args)[current].lalk->buffer[countfile++] = getc(f)) != EOF)
        ;
    fclose(f);
    n = send(newsockfd[current], ((type*)args)[current].lalk->buffer, buflen, 0);
    ((type*)args)[current].lalk->exit = true;
}
int main()
{
    WSADATA ws = { 0 };
    if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)
    {
        currentclient = 0;
        int maxclients = 1;
        cli_addr = new struct sockaddr_in[maxclients];
        clilen = new int[maxclients];
        for (int i = 0; i < maxclients; i++)
        {
            clilen[i] = sizeof(cli_addr[i]);
        }
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
            error("ERROR opening socket");
        struct sockaddr_in serv_addr;
        bzero((char*)&serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        int port = 30000;
        serv_addr.sin_port = htons(port);
        if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
            error("ERROR on binding");
        if (listen(sockfd, 10) < 0)
            error("ERROR listen");
        HANDLE* thread;
        struct arg_sa* args;
        while (true)
        {
            newsockfd = new int[maxclients];
            thread = (HANDLE*)malloc(sizeof(HANDLE) * maxclients);
            args = new struct arg_sa[maxclients];
            for (int i = 0; i < maxclients; i++)
            {
                args[i].lalk = new struct arg_s();
                args[i].lalk->buffer = new char[buflen];
            }
            int i = -1;
            while (++i < maxclients)
            {
                Sleep(1);
                args[i].current = i;
                args[i].lalk->exit = false;
                thread[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)(session_), args, 0, 0);
            }
            while (true)
            {
                int count = 0;
                for (int i = 0; i < maxclients; i++)
                    if (args[i].lalk->exit)
                        count++;
                if (count == maxclients)
                    break;
            }
            i = -1;
            while (++i < maxclients)
            {
                shutdown(newsockfd[i], 0);
                TerminateThread(thread[i], 0);
            }
            delete[] newsockfd;
            free(thread);
            currentclient = 0;
            
            for (int i = 0; i < maxclients; i++)
            {
                delete args[i].lalk;
                //delete[] args[i].lalk->buffer;
            }
            delete[] args;
        }
        shutdown(sockfd, 0);
        WSACleanup();
        return 0;
    }
    std::cin.ignore();
}

Customer:
// ClientOne.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//

#include <iostream>
#include <WinSock.h>
#pragma comment (lib,"WS2_32.lib")
void error(const char* msg)
{
  perror(msg);
  WSAGetLastError();
  WSACleanup();
  std::cin.ignore();
  exit(1);
}
void bzero(char* buf, int l)
{
  for (int i = 0; i < l; i++)
    buf[i] = '\0';
}
int main()
{
  WSADATA ws = { 0 };
  if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)
  {
    int sockfd;
    struct hostent*server = gethostbyname("localhost");
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
      error("ERROR opening socket");
    struct sockaddr_in serv_addr, cli_addr;
    bzero((char*)&serv_addr, sizeof(serv_addr));
    bzero((char*)&cli_addr, sizeof(cli_addr));
    serv_addr.sin_family = AF_INET;
    const char*address="127.0.0.1";
    serv_addr.sin_addr.s_addr = inet_addr(address);
    int port = 30000;
    serv_addr.sin_port = htons(port);
    int servlen = sizeof(serv_addr);
    int n = connect(sockfd, (struct sockaddr*)&serv_addr, servlen);
    if(n < 0)
    {
      error("ERROR on connect");
    }
    int buflen = 100000;
    char* buffer = new char[buflen];
    bzero(buffer, buflen);
    std::string command = "ping 8.8.8.8>1.txt";
        for(int i=0;i<command.size();i++)
            buffer[i] = command[i];
        buffer[command.size()]='\0';
    n = send(sockfd, buffer, buflen, 0);
    if (n < 0)
    {
      error("ERROR on send");
    }
    n = recv(sockfd, buffer, buflen, 0);
    std::cout<<'\n'<< buffer << std::endl;
    shutdown(sockfd, 0);
    WSACleanup();
    delete buffer;
    return 0;
  }
  std::cin.ignore();
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
X
xorknown, 2020-08-22
@xorknown

I'm not completely sure, but in my opinion this line of code is at least worth paying attention to.

while (true)
            {
                int count = 0;
                for (int i = 0; i < maxclients; i++)
                    if (args[i].lalk->exit)
                        count++;
                if (count == maxclients)
                    break;
            }

The fact is that c++ is logically a single-threaded language, so when optimizing, it does not rely on the fact that another thread can change a variable in a loop. And since your structure arg_s (It is better, of course, to use more meaningful names) is not marked in any way, it simply loads the bool variable into the register and spins endlessly in a loop. More details can be read here .
Again, judging by the godbolt , this problem is present, but I'm not sure if you have optimization enabled

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question