powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как разделить сообщения на клиент сервере
10 сообщений из 60, страница 3 из 3
Как разделить сообщения на клиент сервере
    #38513623
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyWhite Owl,

В доке прямо написано, что не следует предполагать что INVALID_SOCKET приводится к -1.Где это написано? Ткни пальцем пожалуйста.
А в winsock2.h есть строчка: #define INVALID_SOCKET (SOCKET)(~0)
Так чта... Оно конечно не -1 с точки зрения компилятора, но...
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38513634
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlГде это написано? Ткни пальцем пожалуйста.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516(v=vs.85).aspx
авторchecking for errors when the socket and accept functions return should not be done by comparing the return value with –1, or seeing if the value is negative (both common and legal approaches in UNIX). Instead, an application should use the manifest constant INVALID_SOCKET


White OwlА в winsock2.h есть строчка
Полагаться надо на АПИ, а не на детали реализации.
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38513637
trom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl,
Anatoly Moskovsky,
MasterZiv,

Сейчас у себя потестил когда клиент подключается на не реальный ип адрес
Функция WSAGetLastError();
возвращает ошибку с кодом 10093
как при отправке так и при получении данных

То есть наметил такую схему программы
После первого подключения клиент при каждой отправке или получении данных ждет ошибку от WSAGetLastError(); с кодом 10093 и если ее получает то пытается подключиться по новой.

Все правильно или опять что не так понял ?
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38513650
wst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Только не так. Соединяться можно и по-прежнему, а вот дальше считать любую ошибку от recv() поводом пересоздать соединение. И еще очень облегчит жизнь вынос приема-отправки сообщений в отдельную пару функций, которые сначала отладить на кошках, потом уже на их основе делать что клиента что сервера.
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38513679
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Начнем с того что ошибка 10093 никакого отношения к ИП адресам или ошибкам подключения не имеет.
Это WSANOTINITIALISED, что означает либо еще не вызван WSAStartup либо уже вызван WSACleanup, то есть сугубо криво написанная программа :)
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38514670
trom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все сделал клиент с обработкой ошибок, покритикуйте!
Все разделено на отдельные функции чтобы было удобно применять в больших проектах, где всякие детали подключения и отправки только будут мешать.
В процессе работы сервер может пропадать и появляться в любое время, прога при пропаже сервака сразу начинает отсчет попыток подключиться, если сервер успевает появиться работает опять в нормальном режиме если нет завершает работу с ошибкой.
Ошибки обрабатываются при каждой отправке или получении данных и при первом подключении к серверу.
Можно задать максимальное количество попыток подключиться и паузу между попытками.

Ошибки обрабатываются просто, если она есть происходит пере подключение, хотя конечно они могут быть из за разных причин, но только эту можно обработать в программе, все остальное ошибки программиста.
Сначала хотел обрабатывать только ошибку 10054, но потом подумал пусть лучше при любой ошибки переподключается.

сервер выложу позже, как понимаю будет попроще, ошибки там обрабатывать не надо, сложности только в нюансах работы с много поточностью.


Код: 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.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
#include <iostream>
#include <stdio.h>
#include <winsock2.h> // Wincosk2.h должен быть раньше windows!
#include <windows.h>

#include <iostream>
#include <conio.h>
#include <fstream>

using namespace std; 

#define MAX_PACKET_SIZE         65535
char* ip="127.0.0.1";
int port=5050;
SOCKET my_sock;

int otpravka_i_polysenie_dannih_CLIENT(string dannie_dla_otpravki, int MAX_count_popitok, int PAUSE_mezdy_popitok);
int recv_all(SOCKET s,  char* buf, int len);
int  otpravka_soobsenia(string text_msg, int MAX_count_popitok, int PAUSE_mezdy_popitok);
int polychenie_soobsenia(char buff[MAX_PACKET_SIZE], int MAX_count_popitok, int &len, int PAUSE_mezdy_popitok);
int podklysenie_k_servery(int MAX_count_popitok, int PAUSE_mezdy_popitok);


int main()
{
	int count_popitok=0, MAX_count_popitok=5, PAUSE_mezdy_popitok=2000, result=1;
	string dannie_dla_otpravki;

	printf("TCP DEMO CLIENT\n");

	result=podklysenie_k_servery(MAX_count_popitok, PAUSE_mezdy_popitok);
	
	if(result==1){
	printf("Soedinenie s %s uspeshno ustanovlenno\n\n", ip);
    dannie_dla_otpravki="MSG OT KLIENTA \n";
	result=otpravka_i_polysenie_dannih_CLIENT(dannie_dla_otpravki, MAX_count_popitok, PAUSE_mezdy_popitok);
		}	

	
	if(result==-1){MessageBoxA(NULL, "Ошибка", "Работа с сервером завершена неудачно", MB_OK);}

	return -1;

}

int otpravka_i_polysenie_dannih_CLIENT(string dannie_dla_otpravki, int MAX_count_popitok, int PAUSE_mezdy_popitok){

	int result=1;

	char  buff[MAX_PACKET_SIZE];

	Sleep(10000);

	int ret=0, i=0;
	

	result=otpravka_soobsenia(dannie_dla_otpravki, MAX_count_popitok, PAUSE_mezdy_popitok);
	
	int len=0;

	if(result==1){
 	while(strcmp(buff, "quit")!=0){ 
 		for (i = 0; i<MAX_PACKET_SIZE; i++){buff[i]=0;}
 
 		result=polychenie_soobsenia(buff, MAX_count_popitok, len, PAUSE_mezdy_popitok);
 		for (i = 0; i<len; i++){printf ("%c", buff [i]);}
 
 		if(len>0&&result==1){	
       	result=otpravka_soobsenia("quit", MAX_count_popitok, PAUSE_mezdy_popitok);
		}
	
	if(result==-1){break;}
	}
	
	
	
	}

closesocket(my_sock);
WSACleanup();

Sleep(10000);

return result;
}
int podklysenie_k_servery(int MAX_count_popitok, int PAUSE_mezdy_popitok){

	int result=-1, count_popitok=0;
	char buff[MAX_PACKET_SIZE];


	while(result==-1&&count_popitok<=MAX_count_popitok){
		
		result=1;

	// Шаг 1 - инициализация библиотеки Winsock
	if (WSAStartup(0x202, (WSADATA *)&buff[0]))
	{
		printf("WSAStart error %d\n", WSAGetLastError());
		result=-1;
	}
	// Шаг 2 - создание сокета
	//SOCKET my_sock;
	my_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (my_sock < 0)
	{
		WSACleanup();
		printf("Socket() error %d\n", WSAGetLastError());
		result=-1;
	}

	// Шаг 3 - установка соединения
	// заполнение структуры sockaddr_in - указание адреса и порта сервера
	sockaddr_in dest_addr;
	dest_addr.sin_family = AF_INET;
	dest_addr.sin_port = htons(port);
	HOSTENT *hst;
	dest_addr.sin_addr.s_addr = inet_addr(ip);

	// адрес сервера получен - пытаемся установить соединение
	if (connect(my_sock, (sockaddr *)&dest_addr, sizeof(dest_addr)))
	{
		closesocket(my_sock);
		WSACleanup();
		printf("Connect error %d\n", WSAGetLastError());
		result=-1;
	}
	
	if(result!=1){		
		closesocket(my_sock);
		WSACleanup();

		printf("Popitka soedinenia #%d neydasna\n", count_popitok);
		Sleep(PAUSE_mezdy_popitok);}
	
	if(count_popitok==MAX_count_popitok&&result==-1){MessageBoxA(NULL, "Ошибка", "Не удалось подключиться к серверу", MB_OK);}
	
	count_popitok++;
	
	}

	


return result;
}
int polychenie_soobsenia(char buff[MAX_PACKET_SIZE], int MAX_count_popitok, int &len, int PAUSE_mezdy_popitok){
	
	int result=1, wsaError=1, recv1=0, count=0;

	while(wsaError/*==10054*/){
		

		if(count>0){
			closesocket(my_sock);
			WSACleanup();
			result=podklysenie_k_servery(MAX_count_popitok, PAUSE_mezdy_popitok);}
		if(result==-1){break;}

	if(recv1==0){
	wsaError=recv_all(my_sock, (char*)&len, sizeof(len));
	if(wsaError){printf("\nRecv error1 %d\n", wsaError);}else{recv1=1;}
		}
	

	
	if(recv1==1){
	wsaError=recv_all(my_sock, buff, len);
	if(wsaError){printf("\nRecv error2 %d\n", wsaError);}
	}
	 
	count++;
	}


	return result;
}
int otpravka_soobsenia(string text_msg, int MAX_count_popitok, int PAUSE_mezdy_popitok){
	int result=1, wsaError=1;
	int len = text_msg.length();
	int send1=0, count=0;

	while(wsaError/*==10054*/){

		if(count>0){
			closesocket(my_sock);
			WSACleanup();
			result=podklysenie_k_servery(MAX_count_popitok, PAUSE_mezdy_popitok);}
		if(result==-1){break;}

	if(send1==0){//Чтобы небыло повторных отправок в случае успешной отправки первого сообщения и ошибки во втором
	send(my_sock, (const char*)&len, sizeof(len), 0);

	wsaError = WSAGetLastError();
	if(wsaError){printf("\nSend error1 %d\n", WSAGetLastError()); printf("result %d\n", result);}else{send1=1;}
	
	}

	if(send1==1){//Если первое сообщение успешно отправлено пытаемся отправить второе
	send(my_sock, text_msg.c_str(), len, 0);

	wsaError = WSAGetLastError();
	if( wsaError )
	{	printf("\nSend error2 %d\n", WSAGetLastError());
		
	}}
	
	 

	count++;
	}
	
	return result;
}
int recv_all(SOCKET s,  char* buf, int len)
{
	int total_recv = 0;
	int bytes_recv;
	int i=0;

	while (len > 0 && (bytes_recv = recv(s, buf + total_recv , len, 0)) > 0) {

		i++;
		total_recv+= bytes_recv;
		len -= bytes_recv;
	}


	return WSAGetLastError();
}
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38514723
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
trom,

Вот это вот


if (WSAStartup(0x202, (WSADATA *)&buff[0]))

что за порнография, а?
расскажи пожалуйста...
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38514835
trom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,

да спасибо!
Я еще сам думал зачем при подключении массив char buff, заменил на кусок из твоего кода

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
	// Шаг 1 - инициализация библиотеки Winsock
	WSADATA wsadata;
	if( WSAStartup(0x202, &wsadata) )
	{
		printf("WSAStart error %d\n", WSAGetLastError());
		return -1;
	}



А так в целом все ок по коду ?
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38514836
trom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,

кстати эту buff автор кода объясняет так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    // Шаг 1 - Инициализация Библиотеки Сокетов
    // т.к. возвращенная функцией информация не используется
    // ей передается указатель на рабочий буфер, преобразуемый к указателю
    // на структуру WSADATA.
    // Такой прием позволяет сэкономить одну переменную, однако, буфер
    // должен быть не менее полкилобайта размером (структура WSADATA
    // занимает 400 байт)
    if (WSAStartup(0x0202, (WSADATA *)&buff[0]))
    {
        // Ошибка!
        printf("Error WSAStartup %d\n", WSAGetLastError());
        return -1;
    }



то есть какая то экономия переменной, но при выносе подключения в отдельную функцию экономии никакой нет.
Да и что вообще за экономия переменной ? первый раз такое слышу
...
Рейтинг: 0 / 0
Как разделить сообщения на клиент сервере
    #38514856
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tromто есть какая то экономия переменной, но при выносе подключения в отдельную функцию экономии никакой нет.
Да и что вообще за экономия переменной ? первый раз такое слышуИзвращение это. Совершенно не нужное и более того - вредное.
Один из источников вредности ты только что увидел: буфер должен быть не менее полкилобайта размером. А если тебе буфер нужен меньшего размера, и ты его уменьшишь не заметив комментария в тексте - получишь либо GPF, либо плавающие ошибки в совершенно разных местах программы, которые будешь долго искать.
Ну и в именах переменных будешь путаться.


В принципе, если ты сидишь на машине с очень маленькой памятью, то это может быть полезным. Этакое "управляемое повторное использование ячеек памяти". Но в реальности такое нужно только на ОЧЕНЬ маленькой памяти. Я таким развлекался последний раз на МК-61, были такие программируемые калькуляторы с 15-ю ячейками памяти. Но уже на Специалисте, имевшем целых 48Кб ОЗУ и на ассемблере (где памятью управлять напрямую можно) осознал что такая экономия памяти может вылезти боком.
...
Рейтинг: 0 / 0
10 сообщений из 60, страница 3 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как разделить сообщения на клиент сервере
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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