11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811

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

14.09.2014, 08:01. Показов 4711. Ответов 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,472
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,472
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,472
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,472
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,472
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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru