Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/21: Рейтинг темы: голосов - 21, средняя оценка - 4.90
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811

Как узнать что соединения уже нет и перезапустить сервер?

14.09.2014, 08:01. Показов 4699. Ответов 31
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Использую сервер с примера: http://msdn.microsoft.com/en-u... s.85).aspx

C++
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
#undef UNICODE
 
#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include <winsock2.h>   
#include <windows.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>
 
#pragma comment(lib, "ws2_32.lib")
 
using namespace std;
 
#define DEFAULT_PORT "10001"
 
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
 
int iSendResult;
 
int __cdecl main(void) 
{
    
    setlocale(LC_ALL, "Russian");
начало1:
    cout <<"Стартсервера"<<endl;
    WSADATA wsaData;
    int iResult;
 
    char recvbuf[512];
    int recvbuflen = 512;
  
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }
 
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;
 
    // Resolve the server address and port
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }
     cout <<"Подключение сокета"<<endl;
    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }
 
    // Setup the TCP listening socket
    iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
 
    freeaddrinfo(result);
 
    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR) {
        printf("listen failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
 
    // Accept a client socket
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET) {
        printf("accept failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
 
    // No longer need server socket
    closesocket(ListenSocket);
 
        //принимаемые пакеты
......тут описываются какие пакеты приходят
        
        //отправляемые пакеты
.......тут описываются отправляемые пакеты
 
    // Receive until the peer shuts down the connection
    do {
        
         ZeroMemory(&recvbuf, sizeof(recvbuf));
        cout <<"Принимаем пакет от смартфона"<<endl;
 
     
        iResult = recv(ClientSocket,recvbuf, recvbuflen, 0);
        recvbuf[--iResult]='\0';
        
        cout << recvbuf <<"  принятый пакет " << endl;
        
    .......тут обрабатываются принятые пакеты и отправляется ответ
            
        if ((iResult == -1)||(iResult == -2))
            {
                printf("Соединение сброшено клиентом: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                goto начало1;
            }
    
            
        if (iSendResult == SOCKET_ERROR) 
            {
                printf("send failed with error: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                goto начало1;
            }
   
 
    } while (iResult > 0);
 
    // shutdown the connection since we're done
    iResult = shutdown(ClientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }
 
   goto начало1;
 
    return 0;
}
Так вот если клиент (это мобильник) сам рвет соединение то сервер заново ждет подключение... а если соединение пропадает по причине выхода телефона из сети то сервер виснет на 117 строчке: iResult = recv(ClientSocket,recvbuf, recvbuflen, 0);
Как узнать что соединения уже нет и перезапустить ?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.09.2014, 08:01
Ответы с готовыми решениями:

Как узнать IP адрес сервера у которого уже нет домена?
Случай такой: есть фтп сервер на него заходил через доменное имя: ftp://domen.ru:port, но недавно домен был заблокирован по неуплате и я...

Как узнать, что тактирование порта уже включено?
Запускаю тактирование, например, PA. RCC-&gt;APB2ENR|= RCC_APB2ENR_IOPAEN; Как узнать, что тактирование уже включено (например,...

Как узнать, что ты уже в интернете, функция InternetGetConnectedState().
Здравствуйте! Есть такая функция InternetGetConnectedState(); из WinInet, так вот делаю так: (все, как написано) ULONG l; ...

31
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
17.09.2014, 14:04  [ТС]
Студворк — интернет-сервис помощи студентам
Чтобы не плодить тем решил спросить здесь.. можно ли отправку данных send сделать в другой функции? или потоке? мне нужно ждать данные это делает основная ветка и если есть команда в это же время отправить устройству команду. ?
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
17.09.2014, 15:10
Цитата Сообщение от eagl69 Посмотреть сообщение
можно ли отправку данных send сделать в другой функции? или потоке? мне нужно ждать данные это делает основная ветка и если есть команда в это же время отправить устройству команду. ?
Зачем? А ваше устройство настолько продвинуто что бы работать в дуплексном режиме? Думаю можно. На свою голову
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
17.09.2014, 17:56  [ТС]
попробовал.. если выносить в функцию отправку то почему то не доходит...
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
18.09.2014, 13:52
смотря как выносить..
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
19.09.2014, 11:49  [ТС]
Ну вот и получилось, принимает данные в одном потоке а отправляет из другого... но опять беда иногда не с того не с сего программа вылетает, мне кажется из -за того что иногда происходит отправка и получение данных через сокет в одно и тоже время... как этого предотвратить?
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
19.09.2014, 14:53
очевидно что нужно блокировать другую операцию пока одна выполняется. например критической секцией.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//где-нибудь где это видно обоим потокам пишем
CRITICAL_SECTION cs;
 
//где-нибудь при запуске программы пишем
InitializeCriticalSection(&cs);
 
//где-нибудь в потоке когда нам нужно захватить общий ресурс
EnterCriticalSection(&cs);
//поработали с ресурсом
...
//освободили
LeaveCriticalSection(&cs);
 
//где-нибудь при завершении программы пишем
DeleteCriticalSection(&cs);
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
19.09.2014, 15:32  [ТС]
Немного не понял.... это по порядку описано?
Цитата Сообщение от vxg Посмотреть сообщение
1

//где-нибудь где это видно обоим потокам пишем
CRITICAL_SECTION cs; - это до запуска потока или после?
//где-нибудь при запуске программы пишем
InitializeCriticalSection(&cs); это должно быть первым?
//где-нибудь в потоке когда нам нужно захватить общий ресурс
EnterCriticalSection(&cs);
//поработали с ресурсом
...
//освободили
LeaveCriticalSection(&cs);
//где-нибудь при завершении программы пишем
DeleteCriticalSection(&cs);
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
19.09.2014, 15:49
Цитата Сообщение от eagl69 Посмотреть сообщение
не понял
1 объявляем объект с типом критическая секция - естественно до обращения к ней то есть до запуска потоков
2 инициализируем его - то же самое
3 используем в потоках (поток которому нужен доступ к разделяемому ресурсу "входит" в критическую секцию, использует ресурс и "выходит" из критической секции; если другой поток захочет "войти" в критическую секцию которая еще не освобождена первым потоком у него ничего не выйдет - он будет блокирован и ожидать "выхода" первого потока; термины "вход", "выход" и секция не должны вводить вас в заблуждение - это просто флажок который мы поднимаем и опускаем - пока он поднят все другие попытки вызвать функцию подъема флажка приведут к ожиданию) - естественно наш флажок должен быть виден потоками. как это другой вопрос. либо передать в них указатель либо объявить как глобальную переменную
4 когда мы закончили пользоваться нашим флажком (в самом конце программы или после выгрузки модуля) нам нужно его удалить
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
19.09.2014, 18:03  [ТС]
А если первый поток будет висеть на функции recv и второй начинает пытаться отправить данные cend то в потоке отправки надо делать:
C++
1
2
3
4
5
EnterCriticalSection(&cs);
//поработали с ресурсом
...
//освободили
LeaveCriticalSection(&cs);
если в это время начнут приходить данные.... то толку от этой блокировки? я думал надо проверть как то перед отправкой не идет ли прием....

Добавлено через 1 минуту
или это сработает?
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
22.09.2014, 09:42
например, если
поток 1:
C++
1
2
3
4
while (true)
{
    ...send...
}
поток 2:
C++
1
2
3
4
while (true)
{
    ...recv...
}
но возникают какие-то странности и есть предположение, что это связано с одновременной работой функций send и recv, то исправив на
поток 1:
C++
1
2
3
4
5
6
while (true)
{
    EnterCriticalSection...
    ...send...
    LeaveCriticalSection...
}
поток 2:
C++
1
2
3
4
5
6
while (true)
{
    EnterCriticalSection...
    ...recv...
    LeaveCriticalSection...
}
можно добиться такой ситуации, при которой эти функции никогда не будут работать одновременно
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
22.09.2014, 11:26  [ТС]
Это хорошая новость теперь понятно.....
0
655 / 576 / 164
Регистрация: 13.12.2012
Сообщений: 2,126
23.09.2014, 11:11
Цитата Сообщение от eagl69 Посмотреть сообщение
а если соединение пропадает по причине выхода телефона из сети то сервер виснет на 117 строчке
неблокирующие сокеты, или мультиплексированный ввод/вывод
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.09.2014, 11:11

Как узнать, что пользователь уже прочитал запись?
Всем привет! Сделал страницу новостей на сайте, теперь хочу сделать так, чтобы когда я добавлял новость, то надо выделять слово Новость в...

Как узнать, что Microsoft Agent уже загружен?
Kak Mozhno usnat shto Agent uzhe sagruzhen. Naprimer ispolsuyu 2 Agenta . I pered tem kak sapustit odnogo is nich nuzhno proverit ...

Нет соединения http сервер
Здравствуйте. Пишу сервер на питоне, клиент на js. Понадобилось выстроить клиент-серверную архитектуру. В качестве средства связи использую...

ADO.Recordset - Как узнать, что запись уже редактируется
Если многопользовательский вариант при доступе ADO.Recordset как узнать что запись кем то модифицируется

Как узнать, отправился ли файл на FTP-сервер или нет?
Всем привет. Из программы создаю bat-файл для отправки файла. Код файла send.bat : ftp -i -s:com.txt del com.txt del send.bat ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Из невошедшего на форум (диалог с ИИ-гугла)
zorxor 29.07.2026
А вот, что интересно, сказал мне ИИ-гугла: Этот текст — эмоциональный пост пользователя под ником zorxor на интернет-форуме (вероятно, посвященном мистике, непознанному или альтернативной науке). . . .
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет Новости компьютерного мира и их обсуждение (4) Салют, шампанское, овации! :drink:
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru