Gremlin92
@Gremlin92
Целеустремленный

Почему программа сервера не дает следующие подключения?

Запускаю сервер рассчитанный на одного клиента после его отключения подключается другой клиент, но никакой реакции бывает со второго клиента бывает но не всегда.
Сервер:
// 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();
}

Клиент:
// 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();
}
  • Вопрос задан
  • 76 просмотров
Пригласить эксперта
Ответы на вопрос 1
xorknown
@xorknown
Будут проблемы - решайте
Не до конца уверен, но по моему на данную строчку кода хотя бы стоит обратить внимание
while (true)
            {
                int count = 0;
                for (int i = 0; i < maxclients; i++)
                    if (args[i].lalk->exit)
                        count++;
                if (count == maxclients)
                    break;
            }


Дело в том, что c++ по логике своей однопоточный язык, поэтому при оптимизации он не опирается на то, что другой поток может изменить переменную в цикле. А так как твоя структура arg_s(Лучше конечно названия более осмысленные применять) никак не помечена, то он просто грузит bool переменную в регистр и бесконечно крутится в цикле. Более подробнее можно прочитать здесь .

Опять же судя по годболту эта проблема и присутствует, но не уверен что у тебя включена оптимизация
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы