Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / При длительном приеме по сокету сервер не принимает данные. / 16 сообщений из 16, страница 1 из 1
23.11.2015, 13:38
    #39110931
roma1975
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Добрый день.
Программа сервер по сокетному соединению принимает данные из вне через порт определённый по ip адресу. Сначала данные принимаются нормально из вне. Потом вроде данные из вне не приходят. Наблюдаю через программу wireshark. Соединение после передачи не разрывается висит на recv в ожидании. Периодически от себя на этот порт с помощью своей программы клиента передаю данные. Данные преданные от себя тоже нормально принимаются в wireshark. Через часика 4 из вне информация программой моей не принимается, а wireshark отображает и для внешних данных и данных от меня такие строки
10004 756.305308000 127.0.0.1 127.0.0.1 TCP 426 [TCP Retransmission] 35667 > 20163 [FIN, PSH, ACK] Seq=1 Ack=1 Win=43776 Len=360 TSval=68865652 TSecr=68865598
Почему не принимается информация? Что тут можно сделать?
...
Рейтинг: 0 / 0
23.11.2015, 14:13
    #39110981
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
roma1975,

FIN означает что посылающая его сторона закрыла сокет.
...
Рейтинг: 0 / 0
23.11.2015, 14:19
    #39110989
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Anatoly MoskovskyFIN означает что посылающая его сторона закрыла сокет.
Точнее, если рассматривать общий случай, посылающая сторона закрыла свое направление сокета (функцией shutdown).
Т.е. передача данных от нее больше невозможна. Поэтому recv на другой стороне не читает данных - их нет ))
...
Рейтинг: 0 / 0
24.11.2015, 06:23
    #39111594
roma1975
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Понятно. И тогда встаёт вопрос: Как отлавливать такое закрытие (функцией shutdown) программно, чтобы мне закрыть сокет свой и заново открыть для ожидания последующего соединения и данных, если программа стоит на recv в ожидании? Или это невозможно?
...
Рейтинг: 0 / 0
24.11.2015, 07:27
    #39111608
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
roma1975,

Покажите для начала ваш код. Возможно там просто ошибка ))
...
Рейтинг: 0 / 0
24.11.2015, 07:54
    #39111621
roma1975
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Код: 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.
void servsokecket(void)
{
            int sock, listener,i1,sock1,n, clilen;
	    struct sockaddr_in addr, cli_addr;
	    char buf2[1024];
	    int bytes_read;
	    int mx = 0;
	    listener = socket(AF_INET, SOCK_STREAM, 0);
	    if(listener < 0)
	    {
	        perror("socket");
	        exit(1);
	    }
	    addr.sin_family = AF_INET;
	    addr.sin_port = htons(atoi(portchwialretr));
	    addr.sin_addr.s_addr = inet_addr(serverchten);
	                    while (1)
	   	    	    {
	   	    	    	sleep(4);
	   	    	    if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	   	    	    {
	   	    	        perror("bind");

	   	    	    }
	   	    	    else
	   	    	    break;
	   	    	    }

             listen(listener, 5);
	     while(1)
	     {
	    	clilen = sizeof(cli_addr);
	    	sock = accept(listener, (struct sockaddr *)&cli_addr, &clilen);
	        if(sock < 0)
	        {
	            perror("accept");
	            exit(3);
	        }
              i1=0;
              int rc,totalcnt,flagoshib,flagpervogchten;
              float d1;
              int chetbiet,nomerbite,nomzapbite, kolbite,r1blok1,i1,c;
              char rasmbl1[4]="";
                 while (1)
            	 {
		     totalcnt = 0;
		     kolbite = 4; // сначала читаем размер
		     char buf_lin2[5000]="";
		     while(totalcnt < kolbite) 
                    {
		        rc=recv(sock, &buf_lin2[totalcnt], kolbite - totalcnt, 0);
		        if (rc<=0)
                        {
		        printf("Сервер не прочитал\n");
		        break;
		        }
			 totalcnt += rc;
			 if (totalcnt == 4)
                         { // прочитали размер
			    memcpy(&kolbite, buf_lin2, 4);
			    if (kolbite==0)
			    {
                            rc=-1;
			    break;
			    }
			    kolbite += 4; // получаем размер всего блока данных
			    if (kolbite > sizeof(buf_lin2)) 
                            {
			     printf("Недостаточный размер буфера\n");
			     break;
			     }
			 }
		     }   
		     if (rc<=0 || kolbite > sizeof(buf_lin2) || kolbite <= 0) break;
		     obrabwialonretr(buf_lin2, sock);
		 }
                  printf("Ожидание следующих данных\n");
            	 close(sock);
           }
}
...
Рейтинг: 0 / 0
24.11.2015, 08:05
    #39111623
roma1975
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Вот принимающая процедура.
...
Рейтинг: 0 / 0
24.11.2015, 09:22
    #39111676
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
roma1975,

Ну, код путанный, но похоже все правильно:
if (rc<=0) - должен поймать закрытие сокета другой стороной или разрыв соединения.

Может еще кто-то заметит что-то.
...
Рейтинг: 0 / 0
24.11.2015, 09:30
    #39111685
roma1975
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Да я тоже так думаю. но видишь, чего иногда приходит-то
10004 756.305308000 127.0.0.1 127.0.0.1 TCP 426 [TCP Retransmission] 35667 > 20163 [FIN, PSH, ACK] Seq=1 Ack=1 Win=43776 Len=360 TSval=68865652 TSecr=68865598
и бывает видать не принимает в какие-то моменты данные. Может некорректно разорвали на предающей стороне связь, не через функцию close(sock), а как-то по другому и у меня программа осталась в recv в ожидании вместо того чтобы принять 0 или -1 и переоткрыть сокет, но я же точно не знаю что происходит на передающей стороне.
...
Рейтинг: 0 / 0
24.11.2015, 09:45
    #39111705
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Пиши принятое в каждом соединении в файлы (все что принял, один файл на одно соединение). Потом пробуй заслать из файла своей проге и смотри как она себя ведет.

Навтыкай отладочных сообщений, чтобы понять на котором месте повисает.

Может ты вовсе неправильно протокол обмена реализовал. Например ты считаешь что первые 4 байта длины сообщения входят в размер сообщения, а передающий может считать что не входят.
...
Рейтинг: 0 / 0
24.11.2015, 09:56
    #39111722
roma1975
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Нет по протоколу описания 4 байта длины сообщения входят в размер сообщения, это протокол wialonretranlator. Да и если бы не работала совсем, я бы данные все не принимал и обрабатывал, а так вроде принимает и обрабатывает, вносит в базу, я вижу, но вот возникают такие непонятные моменты как я написал выше.
...
Рейтинг: 0 / 0
24.11.2015, 10:01
    #39111735
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
roma1975Нет по протоколу описания 4 байта длины сообщения входят в размер сообщения, это протокол wialonretranlator. Да и если бы не работала совсем, я бы данные все не принимал и обрабатывал, а так вроде принимает и обрабатывает, вносит в базу, я вижу, но вот возникают такие непонятные моменты как я написал выше.
Я не утверждаю что ошибка именно тут, написал просто для примера. Описание протокола обмена ты не дал, поэтому можно только гадать что может быть не так. Может все верно и проблема не тут. Пиши принятое в файлы и изучай. Не забывай flush() делать.
...
Рейтинг: 0 / 0
24.11.2015, 11:34
    #39111887
roma1975
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Описание протокола WialonRetranslator 1.0

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Входящие данные.
Все данные приходят в бинарном формате по TCP протоколу и представляют собой пакет
следующего формата:
Размер(байт) Тип поля Описание поля
4 Целое число Размер пакета
- Текстовый Идентификатор контроллера. Данное поле, как
и все другие текстовые поля в протоколе не
имеют фиксированного размера, признаком
конца строки является нулевой байт(00)
4 Целое число Время в секундах(UTC)
4 Целое число Битовые флаги сообщения.
0&#215;1 - информация о положении.
0&#215;2 - информация о цифровых входах
0&#215;4 - информация о цифровых выходах
0&#215;10 - бит тревоги
0&#215;20 - информация о идентификаторе водителя
все остальные биты зарезервированы или
предназначены только для использования в Wialon.
- - Набор блоков данных в пакете, идут
последовательно один за другим


Более полно можно посмотреть здесь:
http://extapi.wialon.com/hw/cfg/WialonRetranslator 1.0.pdf
...
Рейтинг: 0 / 0
24.11.2015, 12:20
    #39111954
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
roma1975,

если не хотите мучиться советую посмотреть в сторону SDL_NET, меньше проблем будет
...
Рейтинг: 0 / 0
24.11.2015, 13:33
    #39112051
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Anatoly MoskovskyМожет еще кто-то заметит что-то.
Ага: он наивно считает, что в каждый момент времени может быть только один коннект. Второй
он замечать отказывается, отчего тот идёт на ретрансмиссии и в конце концов сдаётся. В морг.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
24.11.2015, 13:59
    #39112096
roma1975
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
При длительном приеме по сокету сервер не принимает данные.
Так мне нужно только одно соединение из вне по которому программа бы и получала данные, а другие данные я подавал для проверки как wireshark отображает данные, но почему - то и с одного соединения через какое-то время не происходило приёма данных, перезапускаю программу опять нормально принимает данные. Вообщем не понятно. Сейчас от себя на буду подавать данные в этот порт посмотрим, что будет.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / При длительном приеме по сокету сервер не принимает данные. / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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