powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Многопоточное подключение к серверу из одной программы
49 сообщений из 49, показаны все 2 страниц
Многопоточное подключение к серверу из одной программы
    #38989618
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подключаюсь через сокеты к серверу(127.0.0.1:5555). если одно подключение с одного клиента то работает, по одному подключению с двух клиентов тоже работает. и отправляется сообщение на сервер.
а теперь хочу сделать несколько соединений с одной программы
подключение прописано в функции init
Код: 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.
//---------------client_net

int my_client_net::init(char *ip, int port){

printf("my_client_net init(%s,%i)...\n",ip,port);
WSADATA WsaData;	
int res=0;
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.
my_client_net client[CL_COUNT];
for(int i=0;i<CL_COUNT;i++){
		Sleep(10);
		client[i].clear();
		res[i]=client[i].init(SERVER_IP,5555);
		}



но тут подключение происходит а затем сразу отключается. и при этом ниче не успевает отправится.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989637
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наверно из-за того что WsaData у тебя локальная переменная, которая посте отработки init() становится мусором и затирается другими данными.

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

Тут у тебя совсем нет потоков, как это будет работать -- не очень понятно. Ну, допустим, как-то будет.

Отключает скорее всего сервер, скорее всего он работает по какому-то протоколу уровня приложения поверх TCP, типа POP3 или HTTO, и сервер ждёт, чтобы клиент послал что-то по этому протоколу, инициировал сессию как-то, а этого не происходит,
и, немного подождав, сервер закрывает соединние.

Может быть это и не так в реальности, но по крайней мере ты должен думать, что у тебя происходит и на стороне сервера тоже, а про это ты вообще молчишь.
Если хочешь тестировать только клиента, подключай его к хрестоматийному tcp echo server например (код которого найти можно легоко в сети, и собрать под свою платформу), или аналогичному тестовому TCP-серверу, и проверяй так клиента,
а потом уже будешь подключаться куда-то к другому серверу.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989643
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНаверно из-за того что WsaData у тебя локальная переменная, которая посте отработки init() становится мусором и затирается другими данными.

И WSAStartup() надо однократно вызывать, а не перед каждым соединением.

Ну это -- фишки WinSocks, я в этом не понимаю ничего, но если так, то легко исправить -- перенести эту переменную в класс.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989650
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivчто у тебя происходит и на стороне сервера тоже, а про это ты вообще молчишь.
Если хочешь тестировать только клиента, подключай его к хрестоматийному tcp echo server например (код которого найти можно легоко в сети, и собрать под свою платформу), или аналогичному тестовому TCP-серверу, и проверяй так клиента,
а потом уже будешь подключаться куда-то к другому серверу.

сервер не мой. в чужом коде кавыряться не хотелось бы. просто получается если две программы-клиента запустить (у каждого по одному клиенту) то работает. а если одну с двумя клиентами то не работает
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989655
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежникпри этом ниче не успевает отправится.
Так ты код отправки забыл написать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989659
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежникесли одну с двумя клиентами то не работает
"не работает" понятие растяжимое. Ошибки надо смотреть и анализировать. Что возвращает WSAGetLastError() и в какой момент?

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

сделал теперь работает у меня просто в client[i].clear(); вот такой код

Код: plaintext
1.
2.
3.
4.
void my_client_net::clear(){
printf("my_client_net clear...\n");
WSACleanup();
}



исправил. теперь работает. теперь делаю так запускаю цикл и отправляю с 10 по 100 клиентов с одной проги бесконечные сообщения с задержкой 1мс. серверпринимает около 15000 а затем падает. при отправке сообщений с одного клиента тоже падал после 11000-15000 сообщений
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989709
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежниксерверпринимает около 15000 а затем падает
Удачный эксплоит.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989728
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WSACleanup() надо вызывать после WSAStartup(), а так у тебя получилось что ты инициализировал WSA, установил соединение и перед следующим закрыл все что связано с сетью, в т.ч. ранее открытые соединения.

Вынеси WSAStartup() и WSACleanup() в main(), вызывай их там один раз.

Картежниксерверпринимает около 15000 а затем падает. при отправке сообщений с одного клиента тоже падал после 11000-15000 сообщений
Это уже к разработчику сервера. Чего-то он там накосячил.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989750
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЭто уже к разработчику сервера. Чего-то он там накосячил.
нет это мой косяк.
сервер принимает все, если один клиент отключился, и заново запустить он примет еще 15000

отправляю сообщения Hello World, сервер принимает 15000
оптравляю Hello сервер принмиает в несколько раз(вроде в два раза) больше
вот код как у меня создаются сообщения

Код: 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.
byte msg[1024];
int my_client_net::sendvector(){
	int res=0;
	int len=0;
	int msglen=sendmess.size();
	//int m=msglen;
	//printf("sending... %s %d",msg,msglen);
	//printf("sending %d bytes...",msglen);
	//byte *msg=new byte(msglen);
	for(int i=0;i<msglen;i++){
		msg[i]=sendmess[i];
	}
	msg[msglen]=0;
	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();
		}
			
		
	}
	//delete [] msg;
	//printf("/ %d bytes sended \n",m);
	//printf("/ %s %d bytes sended\n",msg,m);
	return res;
	
}

//здесь создается сообщение по определенному протоколу все закидывается в vector
// на него я и думаю. может он память забивает
int my_client_net::send_msg_to(string msg,int id){
		sendmess.clear(); // здесь стоит очистка вектора может она как то не так очищает 
		sendmess.push_back(245);
		sendmess.push_back(25);
		short l=(short)msg.length();
		write_short(l+10);		
		write_int(id);
		for(int i=0;i<msg.length();i++){
			sendmess.push_back((byte)msg.c_str()[i]);
		}
		sendmess.push_back(0);
		sendmess.push_back(0);
		sendvector();
	return 0;
}



Здесь вызывается функция для создания сообщения и отправки
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
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);
				}
			}
		}
	}
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989769
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КартежникDima TЭто уже к разработчику сервера. Чего-то он там накосячил.
нет это мой косяк.
сервер принимает все, если один клиент отключился, и заново запустить он примет еще 15000

отправляю сообщения Hello World, сервер принимает 15000
оптравляю Hello сервер принмиает в несколько раз(вроде в два раза) больше

...
А ответы принимать кто будет? У тебя в цикле только отправка, приема нет.
Скорее всего сервер забил у себя буфер отправки и у тебя буфер приема ответами на твое Hello, видит что ты обратно ничего не принимаешь и рвет соединение или отвечать перестает.

Для проверки попробуй буфер приема увеличить
Код: plaintext
1.
2.
3.
4.
	int size = 15000000;
	if (setsockopt(serv_socket, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size)) != 0 ) {
		printf("setsockopt SO_RCVBUF failed\n");
	}
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989777
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежникнет это мой косяк.
Падает твоё приложение или сервер? Кто падает - того и косяк.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989872
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТС, и тем не менее, мой совет про отладку клиента на tcp echo server я бы оставил в силе.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989933
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

мое приложение падает. перестает отправлять. а сервер дальше может принимать сообщения от других клиентов.
отправку ответа от сервера отключил.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989936
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сервер и клиент на данный момент находятся на одном компе
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989941
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как насчет того что кол-во отправляемых сообщений зависит от размера сообщения. как я говорил выше, hello world 15000, hello больше где то в 2 раза забыл. запомнить. помню что было больше
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989943
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежникмое приложение падает. перестает отправлять.
"падает" это что? Вылетает? Ошибку выдает? Какую ошибку? В каком месте? Тут телепатов нет, пиши подробнее.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989945
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКартежникмое приложение падает. перестает отправлять.
"падает" это что? Вылетает? Ошибку выдает? Какую ошибку? В каком месте? Тут телепатов нет, пиши подробнее.
падает это перестает отправлять. ошибок никаких не выдает. даже соединения не отключаются.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989947
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежник,

так давай весь код, целиком, как он сейчас есть.
Надеюсь, что всё, о чем уже сказали, ты уже исправил.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989951
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По мне так весь приведённый код -- хрень какая-то. Ничего не понятно, куски какие-то, а не код, и все как-то очень странно.
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989952
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл сказать. до этого когда была отправка ответа от сервера, тогда клиент отправлял 15000 и падал и отключалось соединение.
сейчас отключил отправку ответа. и клиент отправляет не 15000, а 10500 при Hello World! и 144000 при Hello!
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38989960
Фотография Картежник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
60.
61.
62.
63.
64.
65.
66.
class my_client_net{
public:
	vector <byte> sendmess;
	int serv_socket;
	int buffer_size;
	char buffer[MAX_BUF_SIZE];
	string appPath;
	my_packet packet;
	struct sockaddr_in address;
	void clear();
	int init(char *ip, int port);
	bool isconnected(){
		bool res=false;
		if(serv_socket>0)res=true;
		return res;
	}
	void disconnect();
	my_client_net(void);
	virtual ~my_client_net(void);
	int sendmsg(/*const char *buf,int buflen*/);
	int sendmessage(char * msg,int msglen);
	int sendbytes(byte * msg,int msglen);
	int sendvector();
	int getmessage();
	int parse();
	int sendfile(string fname,string fullname);
	int senddir(string dname,string curdir="");
	void sendshortname(string shortname);
	void remove(int n){
		buffer_size-=n;
		for(int i=0;i<buffer_size;i++){
			buffer[i]=buffer[i+n];
		}
	}
	int begin_write(){
		sendmess.clear();
		return 0;
	}
	int write_byte(byte b){
		sendmess.push_back(b);
		return 0;	
	}
	int write_short(short b){
		byte bb[2];
		for (int i =0; i <2; i++){
         bb[i] = (b >> (i * 8));
		}
		//for(int i=1;i>=0;i--)
		for(int i=0;i<2;i++)
		 sendmess.push_back(bb[i]);
		
		return 0;
	}
	int write_int(int b){
		byte bb[4];
		for (int i =0; i <4; i++){
         bb[i] = (b >> (i * 8));
		}
		//for(int i=3;i>=0;i--)
		for(int i=0;i<4;i++)
		 sendmess.push_back(bb[i]);
		
		return 0;
	}
	int send_msg_to(string msg,int id);
};



Код: 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.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
int my_client_net::init(char *ip, int port){

printf("my_client_net init(%s,%i)...\n",ip,port);
WSADATA WsaData;	
	int res=0;
	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;
}



void my_client_net::clear(){
printf("my_client_net clear...\n");
WSACleanup();
}

void my_client_net::disconnect(){
closesocket(serv_socket);
serv_socket=-1;
//clear();
}



byte msg[1024];
int my_client_net::sendvector(){
	int res=0;
	int len=0;
	int msglen=sendmess.size();
	//int m=msglen;
	//printf("sending... %s %d",msg,msglen);
	//printf("sending %d bytes...",msglen);
	//byte *msg=new byte(msglen);
	for(int i=0;i<msglen;i++){
		msg[i]=sendmess[i];
	}
	msg[msglen]=0;
	//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();
		}
			
		
	//}
	//delete [] msg;
	//printf("/ %d bytes sended \n",m);
	//printf("/ %s %d bytes sended\n",msg,m);
	return res;
	
}

int my_client_net::send_msg_to(string msg,int id){
		sendmess.clear();
		sendmess.push_back(245);
		sendmess.push_back(25);
		short l=(short)msg.length();
		write_short(l+10);
		
		write_int(id);
		for(int i=0;i<msg.length();i++){
			sendmess.push_back((byte)msg.c_str()[i]);
		}
		sendmess.push_back(0);
		sendmess.push_back(0);
		sendvector();
	return 0;
}





Код: 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[])
{
	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();
	//b=false;
		
	
	
	
	
	return 0;
}
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #38990006
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Картежник клиент отправлял 15000 и падал и отключалось соединение

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

15000 -- это что ?
15000 сообщений
...
Рейтинг: 0 / 0
Многопоточное подключение к серверу из одной программы
    #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
49 сообщений из 49, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Многопоточное подключение к серверу из одной программы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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