powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Многопоточное подключение к серверу из одной программы
24 сообщений из 49, страница 2 из 2
Многопоточное подключение к серверу из одной программы
    #38990008
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежник,

Ты исправил то, что тебе уже говорили в данном топике ?
Нет, я вижу, не исправил .
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990009
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежник,

авторWSAStartup function

The WSAStartup function initiates use of the Winsock DLL by a process.
...
Remarks

The WSAStartup function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets required and retrieve details of the specific Windows Sockets implementation. The application or DLL can only issue further Windows Sockets functions after successfully calling WSAStartup.


Её один раз во всей программе звать надо, а ты на каждое соединение её вызываешь.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990012
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

сейчас 5 сек проверю
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990015
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivКартежник,

авторWSAStartup function

The WSAStartup function initiates use of the Winsock DLL by a process.
...
Remarks

The WSAStartup function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets required and retrieve details of the specific Windows Sockets implementation. The application or DLL can only issue further Windows Sockets functions after successfully calling WSAStartup.


Её один раз во всей программе звать надо, а ты на каждое соединение её вызываешь.
поставил один раз в функц майн. а в других местах убрал
проверил все так же.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990016
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КартежникMasterZivКартежник,

пропущено...


Её один раз во всей программе звать надо, а ты на каждое соединение её вызываешь.
поставил один раз в функц майн. а в других местах убрал
проверил все так же.

Я в этом не сомневался, только надо с самого начала было делать всё правильно.

Новый код давай, да ?
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990021
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
int my_client_net::init(char *ip, int port){

printf("my_client_net init(%s,%i)...\n",ip,port);
	
	int res=0;
	bool wsas=true;
	if (wsas){
	//if (WSAStartup( MAKEWORD(2,2), &WsaData ) == NO_ERROR){
	int opt = TRUE;
	int iResult=0;
	printf("my_client_net WSAStartup success\n");
	if( (serv_socket = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP)) == 0) 
	{
		printf("socket failed");
		res=-1;
	}
	if(res==0){
		//set master socket to allow multiple connections , this is just a good habit, it will work without this
		if( setsockopt(serv_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 )
		{
			printf("setsockopt failed");
			res=-1;
		}
	}
	
	if(res==0){
		int flag = 1;
		iResult = setsockopt(serv_socket,      // socket affected 
								IPPROTO_TCP,     // set option at TCP level 
								TCP_NODELAY,     // name of option 
								(char *) &flag,  // the cast is historical cruft 
								sizeof(int));    // length of option value 
		if (iResult < 0)
		{
			printf("set TCP_NODELAY ERROR\n");
			res=-1;
		}
	}
	if(res==0){
		memset(&address, 0, sizeof(address));
		address.sin_family = AF_INET;
		address.sin_addr.s_addr = inet_addr( ip );//INADDR_ANY;
		address.sin_port = htons( port );
		if(connect(serv_socket, (struct sockaddr *)&address, sizeof(struct sockaddr))<0){
			printf("can't connect\n");
			//printf("send() failed with error: %d\n", WSAGetLastError());
			res=-1;
		}
		
	}
	
	}
	else{
		printf("my_client_net failed WSAStartup\n");
		res=-1;
	}

return res;
}





Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
#include "stdafx.h"
#define CL_COUNT 99
my_client_net client[CL_COUNT];

int _tmain(int argc, _TCHAR* argv[])
{WSADATA WsaData;
	if (WSAStartup( MAKEWORD(2,2), &WsaData ) == NO_ERROR){
	setlocale(LC_CTYPE, "rus");
	int result=0;
	int res[CL_COUNT];
	
	//client[0].clear();
	for(int i=0;i<CL_COUNT;i++){
		Sleep(1);
		
		res[i]=client[i].init(SERVER_IP,5555);
		}
	bool b=true;
	int uid=0;
	string pl="PLAYER1",msg="HELLO";
					
	while(b){
		Sleep(1);
		//b=false;
		for(int i=0;i<CL_COUNT;i++){
			if(res[i]==0){
				if(client[i].isconnected()){
				b=true;
						uid++;
						/*if(uid>105000){
							//printf("send() failed with error:%d %d\n", WSAGetLastError(),uid);
						}*/
					client[i].send_msg_to("HELLO!",uid);
				}
			}
		}
	}

	for(int i=0;i<CL_COUNT;i++){
		client[i].disconnect();
	}
	client[0].clear();
	

	}	
	
	
	return 0;
}
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990127
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежникпадает это перестает отправлять. ошибок никаких не выдает. даже соединения не отключаются.
Ппц, кто тебе их должен выдавать? Не на VB пишешь. Сам проверяй, пиши в коде проверки, WSAGetLastError() в помощь. Проверяй везде где общение с сетью не удалось, пиши в лог/на экран, дальше разбирайся почему так.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990254
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
покавырялся
выяснил что

что сообщение отправляется с клиента, а до сервера не доходит или он не принимает
на клиенте показывает что отправил 105895, а на сервере 105894
решил пошагово просмотреть
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
while (msglen>0){
		len=send(serv_socket,(char*)msg,msglen,0); // вот тут останавливается работа клиента и дальше ничего не происходит
		if(msglen!=len) printf("> send part");
		if(len>0){
			msglen-=len;
			for(int i=0;i<msglen;i++){
				msg[i]=msg[i+len];
			}
		}
		else{
			printf("send() failed with error: %d\n", WSAGetLastError());
			msglen=0;
			disconnect();
		}
			
		
	}


в то время как сервер может и дальше принимать сообщения от других клиентов
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990258
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
send() блокируется пока отправка не произойдет. Добавь проверку готовности сокета к отправке
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
			timeval wait_time = {0};
			fd_set fd;	
			FD_ZERO(&fd);
			FD_SET(serv_socket, &fd);
			int sel = select(serv_socket + 1, NULL, &fd, NULL, &wait_time);
			if(!FD_ISSET(serv_socket, &fd)) {
				printf("socket is full\n");
			} else {
				len=send(...
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990260
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tsend() блокируется пока отправка не произойдет. Добавь проверку готовности сокета к отправке
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
			timeval wait_time = {0};
			fd_set fd;	
			FD_ZERO(&fd);
			FD_SET(serv_socket, &fd);
			int sel = select(serv_socket + 1, NULL, &fd, NULL, &wait_time);
			if(!FD_ISSET(serv_socket, &fd)) {
				printf("socket is full\n");
			} else {
				len=send(...



добавил, также и потом выводит socket is full. на клиенте проблема или на сервере?
я сделал свой другой сервер, отправляю туда уходит бесконечно.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990284
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
на клиенте после 105895 сообщений бесконечно выходит socket is full
код с клиента
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
	while (msglen>0){

		timeval wait_time = {0};
			fd_set fd;	
			FD_ZERO(&fd);
			FD_SET(serv_socket, &fd);
			int sel = select(serv_socket + 1, NULL, &fd, NULL, &wait_time);
			if(!FD_ISSET(serv_socket, &fd)) {
				//printf("socket is full\n");
			} else {
				//len=send(...
				len=send(serv_socket,(char*)msg,msglen,0);
		
				if(msglen!=len) printf("> send part");
				if(len>0){
					msglen-=len;
					for(int i=0;i<msglen;i++){
						msg[i]=msg[i+len];
					}
				}
				else{
					printf("send() failed with error: %d\n", WSAGetLastError());
					msglen=0;
					disconnect();
				}
			
			}
	}



на серваке пишет что нет данных код с сервака
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
	for (index = 0; index < MAX_PLAYERS; index++) 
	{	
		s = client_socket[index];
		if (!FD_ISSET( s , &readfds)){ 
			printf("net dannyh\n");
			continue; //нет данных в сокете
		}
		//printf("begin cycle\n");	
		
		// определяем сколько байт мы можем еще прочетать
		// это исправляет фикс когда байт траффик не влезает в буффер
		// в оригинале стояло maxread постоянно 1024, тем самым могло перезаписать буффер.
		maxread = RECV_BUFFER_SIZE-splitread[index];		//фиксируем maxread, чтобы не записать сверх буффер'а
		if (maxread>1024) maxread=1024;
		
		valread = recv( s , (char *)&recvbuffer[index][splitread[index]], maxread, 0);
		if (valread==0)														//closed by client
		{
			client_disconnect(index);
			continue;
		}
		
		if (valread==SOCKET_ERROR && GetLastError( ) != WSAEWOULDBLOCK )	//closed with error
		{
			client_disconnect(index);
			continue;
		}
.......
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990309
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежникдобавил, также и потом выводит socket is full. на клиенте проблема или на сервере?
Сервер не забирает данные, поэтому на клиенте заполнился буфер. Может сервер закрыл соединение.

Добавь проверку что сокет рабочий:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
...
			printf("socket is full\n");
			FD_ZERO(&fd);
			FD_SET(serv_socket, &fd);
			int sel = select(serv_socket + 1, NULL, NULL, &fd, &wait_time);
			if(sel == -1) {
				printf("error1 %d\n", WSAGetLastError());
			if(FD_ISSET(serv_socket, &fd)) {
				printf("error2 %d\n", WSAGetLastError());
			}
...
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990317
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не дописал немного
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
...
			printf("socket is full\n");
			FD_ZERO(&fd);
			FD_SET(serv_socket, &fd);
			int sel = select(serv_socket + 1, NULL, NULL, &fd, &wait_time);
			if(sel == -1) {
				printf("error1 %d\n", WSAGetLastError());
			} else if(FD_ISSET(serv_socket, &fd)) {
				printf("error2 %d\n", WSAGetLastError());
			}
...
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990318
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
также
только теперь бесконечно выходит "error2 0"
а socket is full не выходит
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
while (msglen>0){


			FD_ZERO(&fd);
			FD_SET(serv_socket, &fd);
			int sel = select(serv_socket + 1, NULL, &fd, NULL, &wait_time);
			if(sel == -1) {
				printf("error1 %d\n", WSAGetLastError());
				
			}
			if(FD_ISSET(serv_socket, &fd)) {
				printf("error2 %d\n", WSAGetLastError());
			}
			if(!FD_ISSET(serv_socket, &fd)) {
				printf("socket is full\n");
			} else {
				//len=send(...
				len=send(serv_socket,(char*)msg,msglen,0);
...
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990319
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
теперь получается так пока на сервере все сообщения не поступят пишет error2 0,
после того как сервер отобразит все полученные сообщения клиент пишет socket is full

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
while (msglen>0){


			FD_ZERO(&fd);
			FD_SET(serv_socket, &fd);
			int sel = select(serv_socket + 1, NULL, &fd, NULL, &wait_time);
			if(sel == -1) {
				printf("error1 %d\n", WSAGetLastError());
				
			}
			else if(FD_ISSET(serv_socket, &fd)) {
				printf("error2 %d\n", WSAGetLastError());
			}
			if(!FD_ISSET(serv_socket, &fd)) {
				printf("socket is full\n");
			} else {
				//len=send(...
				len=send(serv_socket,(char*)msg,msglen,0);
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990322
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежниктолько теперь бесконечно выходит "error2 0"
а socket is full не выходит
у select() три набора сокетов, первый - есть что читать, второй - готов к отправке, третий - проверка на ошибки
надо оба select()
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
		timeval wait_time = {0};
		fd_set fd;	
		FD_ZERO(&fd);
		FD_SET(serv_socket, &fd);
		int sel = select(serv_socket + 1, NULL, &fd, NULL, &wait_time); // проверка готовности к отправке
		if(!FD_ISSET(serv_socket, &fd)) {
			printf("socket is full\n");
			FD_ZERO(&fd);
			FD_SET(serv_socket, &fd);
			int sel = select(serv_socket + 1, NULL, NULL, &fd, &wait_time); // проверка работоспособности
			if(sel == -1) {
				printf("error1 %d\n", WSAGetLastError());
			} else if(FD_ISSET(serv_socket, &fd)) {
				printf("error2 %d\n", WSAGetLastError());
			} else {
				printf("no error\n");
			}
		} else {
			len=send(...

...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990354
ART-CODE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tl;dr
Посмотрите на Boost.Asio
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990430
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
63 подключенных клиента сервер принимает сообщения бесконечно.
если больше то останавливается (не прием сообщений, а отправка на клиенте)
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990471
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежник63 подключенных клиента сервер принимает сообщения бесконечно.
если больше то останавливается (не прием сообщений, а отправка на клиенте)
Это ограничение сервера.
Если сервер использует select() для ожидания сообщений клиентов, то fd_set по умолчанию принимает 64 сокета
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx Four macros are defined in the header file Winsock2.h for manipulating and checking the descriptor sets. The variable FD_SETSIZE determines the maximum number of descriptors in a set. ( The default value of FD_SETSIZE is 64 , which can be modified by defining FD_SETSIZE to another value before including Winsock2.h.)
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990484
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКартежник63 подключенных клиента сервер принимает сообщения бесконечно.
если больше то останавливается (не прием сообщений, а отправка на клиенте)
Это ограничение сервера.
Если сервер использует select() для ожидания сообщений клиентов, то fd_set по умолчанию принимает 64 сокета
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx Four macros are defined in the header file Winsock2.h for manipulating and checking the descriptor sets. The variable FD_SETSIZE determines the maximum number of descriptors in a set. ( The default value of FD_SETSIZE is 64 , which can be modified by defining FD_SETSIZE to another value before including Winsock2.h.)

аха а как мне его увеличть, не подскажите?
на сервере стоит
Код: plaintext
1.
2.
3.
4.
5.
#define MAX_PLAYERS 100
...

activity = select( MAX_PLAYERS + 3 , &readfds , NULL , NULL , &tv);
...


но все равно 63 соединения
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990496
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежникаха а как мне его увеличть, не подскажите?
Там же написано: задефайнить перед winsock2.h, т.е.
Код: plaintext
1.
2.
#define FD_SETSIZE 100
#include <winsock2.h>



По-хорошему, если сервер будет обслуживать одновременно много соединений, лучше взять какую-нибудь библиотеку, например: libevent или boost.asio
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990503
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
все сделал нормально теперь

в майн файле надо было задать FD_SETSIZE
Код: plaintext
1.
2.
3.
4.
5.
#if !defined MAIN_H
#define MAIN_H

#define MAX_PLAYERS 100
#define FD_SETSIZE  MAX_PLAYERS
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990506
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКартежникаха а как мне его увеличть, не подскажите?
Там же написано: задефайнить перед winsock2.h, т.е.
Код: plaintext
1.
2.
#define FD_SETSIZE 100
#include <winsock2.h>



По-хорошему, если сервер будет обслуживать одновременно много соединений, лучше взять какую-нибудь библиотеку, например: libevent или boost.asio
ну или так. с бустой кавырялся до этого че то сликшом сложно. пока просто установил чтоб компилилась стока времени потерял. а потом надо было на QT чтоб использовалась, там так и не смог скомпилить без ошибок
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990556
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежникс бустой кавырялся до этого че то сликшом сложно.
libevent посмотри, он попроще.
...
Рейтинг: 0 / 0
24 сообщений из 49, страница 2 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Многопоточное подключение к серверу из одной программы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]