Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219

Как только происходит попытка создать сокет для UDP - сокет TCP сразу ломается (выдает 10093).

01.02.2016, 09:58. Показов 3928. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день.
Пытаюсь сделать соединение, использующее два канала обмена данными - TCP для управления в режиме клмиента, и UDP - для приема данных в режиме сервера.

Собственно код выглядит так:

Инициализация для TCP:
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
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
CSoIPInterface::CSoIPInterface(DWORD dwIP, long aPort, long aBaudRate, long aReadTimeout, logger::ILogger *pLogger):
    m_dwIP(dwIP),
    m_lPort(aPort),
    m_lBaudRate(aBaudRate),
    m_lReadTimeout(aReadTimeout),
    m_sock(INVALID_SOCKET),
    m_pLogger(pLogger),
    m_last_connect_try(0),
    sendingrequests(0)
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);
    OpenPort();
}
 
long CSoIPInterface::OpenPort()
{
    if(m_sock != INVALID_SOCKET)
        Close();
 
    m_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    sockaddr_in devSoIP_addr;
    devSoIP_addr.sin_family             = AF_INET;
    devSoIP_addr.sin_addr.S_un.S_addr   = htonl(m_dwIP);
    devSoIP_addr.sin_port               = htons((u_short)m_lPort);
 
    timeval timeout = {0};
    timeout.tv_usec = m_lReadTimeout;
 
    unsigned long iMode = 1;
    int iRes = ioctlsocket(m_sock, FIONBIO, &iMode);
 
    m_last_connect_try = GetTickCount();
 
    if(connect(m_sock,(struct sockaddr *)&devSoIP_addr,sizeof(devSoIP_addr))==false)
    {
        if(m_pLogger)
            m_pLogger->Log(logger::LL_ERROR, L"Failed to connect to SoIP device: %S port: %i",
                            inet_ntoa(devSoIP_addr.sin_addr),m_lPort);
        return false;
    }   
 
    // restart the socket mode
    iMode = 0;
    iRes = ioctlsocket(m_sock, FIONBIO, &iMode);
 
    fd_set Write, Err;
    FD_ZERO(&Write);
    FD_ZERO(&Err);
    FD_SET(m_sock, &Write);
    FD_SET(m_sock, &Err);
 
    //Magic sleep for socket become ready to connect
    Sleep(10);
 
    // check if the socket is ready
    select(0, NULL, &Write, &Err, &timeout);            
    if(FD_ISSET(m_sock, &Write)) 
    {
        if(m_pLogger)
            m_pLogger->Log(logger::LL_OK, L"Successfully connected to SoIP device: %S port: %i",
                            inet_ntoa(devSoIP_addr.sin_addr),m_lPort);
        setsockopt(m_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
        setsockopt(m_sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
        return true;
    }
    else
    {
        if(m_pLogger)
            m_pLogger->Log(logger::LL_ERROR, L"Failed to connect to SoIP device: %S  port: %i",
                            inet_ntoa(devSoIP_addr.sin_addr),m_lPort);
        Close();
        return iRes;
    }
}
 
long CSoIPInterface::Write(void* pData, size_t iLen, size_t* pdwWritten)
{
    int bResult = 0;
 
    std::vector<char> pBuffer(128, 0);
 
    if (iLen > 128)
        iLen = 128;
 
    size_t nNumberOfBytesWritten = 0;
 
    memcpy(pBuffer.data(), pData, iLen);
 
    if (m_sock == INVALID_SOCKET && IsReadyToConnect())
    {
            Close();
            OpenPort();
    }
     
    if (m_sock != INVALID_SOCKET)
        bResult = send(m_sock, pBuffer.data(), iLen, 0);
    else
        bResult = SOCKET_ERROR;
 
    if (bResult == SOCKET_ERROR)
    {
        sendingrequests++;
        if(sendingrequests >= maxsendingrequest)
        {
            Close();
        }
    }
    else
    {
        sendingrequests = 0;
    }
 
    nNumberOfBytesWritten = bResult;
 
    if(pdwWritten) *pdwWritten = nNumberOfBytesWritten;
 
    return (bResult == 0 || nNumberOfBytesWritten != iLen) ? 1 : 0;
}
 
long CSoIPInterface::Read(void* pData, size_t iLen, size_t* pdwRead)
{
    BOOL bResult = 0;
 
    std::vector<char> pBuffer(128, 0);
    DWORD nNumberOfBytesToRead;
    DWORD nNumberOfBytesReaded;
 
    if (iLen > 128)
        iLen = 128;
    nNumberOfBytesToRead = (DWORD)iLen;
    nNumberOfBytesReaded = 0;
 
    timeval timeout = {0};
    timeout.tv_usec = m_lReadTimeout;
 
    bool bReady = true;
    DWORD nBeg = GetTickCount();
    DWORD nTimeout = 0;
    // check if the socket is ready
    do 
    {
        fd_set Read, Err;
        FD_ZERO(&Read);
        FD_ZERO(&Err);
        FD_SET(m_sock, &Read);
        FD_SET(m_sock, &Err);
 
        select(0, &Read, NULL, &Err, &timeout);
 
        bReady = (FD_ISSET(m_sock, &Read) != 0);
 
        nTimeout = GetTickCount() - nBeg;
    }
    while( !bReady && ((GetTickCount() - nBeg) < (DWORD)m_lReadTimeout) );
 
    if (bReady)
    {
        nNumberOfBytesReaded = recv(m_sock, pBuffer.data(), nNumberOfBytesToRead, 0);
        bResult = nNumberOfBytesReaded;
    }
    else
    {
        bResult = SOCKET_ERROR;
    }
 
    if (bResult == SOCKET_ERROR)
    {
        nNumberOfBytesReaded = 0;
        if(sendingrequests >= maxsendingrequest)
        {
            Close();
        }
    }
 
    memcpy(pData, pBuffer.data(), iLen);
 
    if (pdwRead)
        *pdwRead = nNumberOfBytesReaded;
 
    // Check for end of file. 
    if (bResult &&  nNumberOfBytesReaded == 0) 
    { 
        // we're at the end of the file 
        return 2;
    }
 
    if (nNumberOfBytesReaded < iLen)
        return 2;
 
    return bResult ? 0 : 1;
}
 
long CSoIPInterface::Flush()
{
    std::vector<char> pBuffer(128, 0);
 
    timeval timeout = {0};
    timeout.tv_usec = m_lReadTimeout;
 
    bool bReady = true;
    DWORD nBeg = GetTickCount();
    // check if the socket is ready
    do 
    {
        fd_set Read, Err;
        FD_ZERO(&Read);
        FD_ZERO(&Err);
        FD_SET(m_sock, &Read);
        FD_SET(m_sock, &Err);
 
        select(0, &Read, NULL, &Err, &timeout);
 
        bReady = (FD_ISSET(m_sock, &Read) != 0);
    }
    while( !bReady && ((GetTickCount() - nBeg) < (DWORD)m_lReadTimeout) );
    
    int flushed = 0;
    if (bReady)
    {
        flushed = recv(m_sock, pBuffer.data(), pBuffer.size(), 0);
    }
    return flushed;
}
Инициализация для UDP:
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
bool CUDPServer::Start()
{
    Stop(); 
    {
        WSADATA wsa;
        m_socket = SOCKET_ERROR;
 
        try
        {
            //init winsock
            if ( WSAStartup(MAKEWORD(2,2),&wsa) != 0 )
            {
                if ( m_logger )
                    m_logger->Log(logger::LL_ERROR, L"WSAStartup() error");
                return false;
            }
            //throw std::wstring(L"WSAStartup() error");
 
            //create socket
            if ( (m_socket=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR )
            {
                if ( m_logger )
                    m_logger->Log(logger::LL_ERROR, L"socket() error");
                return false;
            }
                //throw std::wstring(L"socket() error");
 
            timeval tv;
            tv.tv_sec  = NET_CONNECT_TIMEOUT/1000;
            tv.tv_usec = 0;
 
            if ( setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)) == SOCKET_ERROR )
            {
                if ( m_logger )
                    m_logger->Log(logger::LL_ERROR, L"setsockopt() error");
                return false;
            }
 
            int buffsize = kMaxPacketSize;
            if ( setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<const char*>(&buffsize), sizeof(buffsize)) == SOCKET_ERROR )
            {
                if ( m_logger )
                    m_logger->Log(logger::LL_ERROR, L"setsockopt() error");
                return false;
            }
 
            //configure listen address
            sockaddr_in listen_addr;
            memset((char *) &listen_addr, 0, sizeof(listen_addr));
            listen_addr.sin_family = AF_INET;
            listen_addr.sin_port = htons((u_short)UDP_PORT);//htons(kPortToListen);
            listen_addr.sin_addr.S_un.S_addr =  INADDR_ANY;
 
            //we must bind incoming message port for recv() (or call sendto() first)
            if( bind(m_socket ,(struct sockaddr *)&listen_addr, sizeof(listen_addr)) == SOCKET_ERROR )
            {
                if ( m_logger )
                    m_logger->Log(logger::LL_ERROR, L"bind() error");
                return false;
            }
            //throwstd::wstring(L"bind() error");                   
        }
        catch (std::wstring s)
        {
            //m_logger->Log( logger::LL_ERROR, s.c_str());
            return false;
        }
        catch(...)
        {
            //m_logger->Log(logger::LL_ERROR, L"UDPThread: unknown error;");
            return false;
        }
 
        sockaddr_in sender_addr;
        int sender_addr_size = sizeof(sender_addr);
        int bytes_recv = recvfrom(m_socket, m_recv_buffer.data(), kMaxPacketSize, 0, (struct sockaddr *) &sender_addr, &sender_addr_size);  
 
        if ( bytes_recv == SOCKET_ERROR )
        {
            int error_code = WSAGetLastError();
            Stop();
            if ( m_logger )
                m_logger->Log(logger::LL_ERROR, L"Failed UDP connect with code %d...", error_code);
            return false;
        }
        else
        {
            if ( m_logger )
                m_logger->Log(logger::LL_OK, L"Start UDP connect...");
        }
 
    }
    
    return true;
 
}
Собственно проблема в следующем:
При запуске соединение TCP работает и управление собственно тоже - как запись, так и прием.
Как только происходит попытка создать сокет для UDP - сокет TCP сразу ломается (выдает 10093).
И подобное происходит при каждой попытке установить UDP соединение.

Причем когда я UDP инициализировал как клиент - все работало без сбоев (в плане TCP сокета). Но меня интересует именно режим сервера.

Подскажите в чем может быть проблема и как ее поправить.

Добавлено через 5 часов 19 минут
Пробовал делать так:

C++
1
2
3
4
5
6
//configure listen address
            sockaddr_in listen_addr;
            memset((char *) &listen_addr, 0, sizeof(listen_addr));
            listen_addr.sin_family = AF_INET;
            listen_addr.sin_port = htons((u_short)UDP_PORT);//htons(kPortToListen);
            listen_addr.sin_addr.S_un.S_addr =  inet_addr("10.0.0.1");
Перестала работать функция bind()

Добавлено через 1 минуту
Думаю надо как то еще настроить...

Если поможет - TCP соединяется с одним адресом, например 10.0.0.2, а UDP с другим, например 10.0.0.3...

Добавлено через 12 часов 0 минут
с bind понял - нужно установить либо INADDR_ANY, либо локальный адрес карты, либо 127.0.0.1 .
Но это в любом случае не помогло бы, думаю при инициализации нужно как то ограничить ip-адреса, с которых принимаются данные, т.е. для TCP это прописано, т.к. это клиент, возможно нужно сделать так же для UDP, оставив его при этом сервером.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.02.2016, 09:58
Ответы с готовыми решениями:

Один сокет для TCP и UDP
Привет. Клиент-серверное приложение в один промежуток времени использует TCP, но через некоторое время нужно начать передавать и принимать...

TCP сокет: доходит только каждое пятое сообщение
Добрый день! Можно ли организовать передачу таким образом? Клиент сначала в цикле передает несколько сообщений серверу, сервер их принимает...

Как часто можно открывать TCP сокет?
Нужно опрашивать некое устройство по TCP раз в секунду. Запрос и ответ по 40 байт. На клиентской стороне Raspberry, Linux, Qt,...

13
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
01.02.2016, 10:06
Цитата Сообщение от Leardjiny Посмотреть сообщение
C++
1
if ( WSAStartup(MAKEWORD(2,2),&wsa) != 0 )
предположу что повторную инициализацию делать не нужно, она же сделана ранее(TCP сокет создавался ранее)
Цитата Сообщение от Leardjiny Посмотреть сообщение
с bind понял - нужно установить либо INADDR_ANY, либо локальный адрес карты, либо 127.0.0.1 .
да верно, если INADDR_ANY то соединения будут приняты с любой сетевой карты, если "локальный адрес карты", то с конкретной
Цитата Сообщение от Leardjiny Посмотреть сообщение
Но это в любом случае не помогло бы, думаю при инициализации нужно как то ограничить ip-адреса, с которых принимаются данные, т.е. для TCP это прописано, т.к. это клиент, возможно нужно сделать так же для UDP, оставив его при этом сервером.
это тут совсем не причем
1
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
01.02.2016, 11:12  [ТС]
Да, Вы правы. Спасибо.
Перенес WSAStartup() в конструктор, стало лучше. Теперь при начальном запуске оба сокета подхватываются и работают совместно.

Осталась проблема с реинициализацией.
Т.е. когда я во время работы приложения делаю рестарт соединений - происходит следующее:
1) Для UDP соединения происходят функции stop, установка новых настроек (ip, port) и затем start;
2) Для TCP соединения делаю reinit - удаляю класс и вызываю конструктор заново с новыми настройками (ip,port).

После этого устанавливается только одно соединение, а второе не запускается. Причем заранее непонятно какое включится, а какое - нет (возможно связано с тем - кто первый инициализируется).
С чем это может быть связано?

Собственно коды конструкторов и функции stop привел ниже. Они совпадают для обоих соединений.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void CSoIPInterface::Close()
{
    if (m_sock != INVALID_SOCKET)
    {
        shutdown(m_sock, SD_BOTH);
        closesocket(m_sock);
        m_sock = INVALID_SOCKET;
    }
}
 
CUDPServer::CUDPServer(  logger::ILogger *logger) :
    m_logger(logger)
    {
    m_socket = SOCKET_ERROR;
 
    //init winsock
    WSADATA wsa;
    if ( WSAStartup(MAKEWORD(2,2),&wsa) != 0 )
    {
        if ( m_logger )
            m_logger->Log(logger::LL_ERROR, L"WSAStartup() error");
    }
}
Добавлено через 1 минуту
Может проблема быть в том что WSAStartup вызывается для обоих соединений?
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
01.02.2016, 11:14
опять же
Цитата Сообщение от Leardjiny Посмотреть сообщение
WSAStartup(MAKEWORD(2,2),&wsa) != 0
уберите уже это в мейн и все, не надо этого делать в конструкторах, а если и делать то только в одном, и только в том который создается самым первым

Добавлено через 59 секунд
Цитата Сообщение от Leardjiny Посмотреть сообщение
После этого устанавливается только одно соединение, а второе не запускается. Причем заранее непонятно какое включится, а какое - нет (возможно связано с тем - кто первый инициализируется).
С чем это может быть связано?
TCP к пример может не забиндиться повторно на только что закрытый адрес(айпи порт) для этого надо выставлять опцию SO_REUSEADDR
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
01.02.2016, 12:04  [ТС]
Сделал.
Теперь при реинициализации соединение устанавливается в обоих случаях.
Но для TCP не всегда сразу - иногда с 5-6 попытки.

Правильно выставлен параметр SO_REUSEADDR?

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
long CSoIPInterface::OpenPort()
{
    if(m_sock != INVALID_SOCKET)
        Close();
 
    m_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 
    int reuse = 1;
    setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
        
    sockaddr_in devSoIP_addr;
    devSoIP_addr.sin_family             = AF_INET;
    devSoIP_addr.sin_addr.S_un.S_addr   = htonl(m_dwIP);
    devSoIP_addr.sin_port               = htons((u_short)m_lPort);
 
    timeval timeout = {0};
    timeout.tv_usec = m_lReadTimeout;
 
    unsigned long iMode = 1;
    int iRes = ioctlsocket(m_sock, FIONBIO, &iMode);
 
    m_last_connect_try = GetTickCount();
 
    if(connect(m_sock,(struct sockaddr *)&devSoIP_addr,sizeof(devSoIP_addr))==false)
    {
        if(m_pLogger)
            m_pLogger->Log(logger::LL_ERROR, L"Failed to connect to SoIP device: %S port: %i",
                            inet_ntoa(devSoIP_addr.sin_addr),m_lPort);
        return false;
    }   
 
    // restart the socket mode
    iMode = 0;
    iRes = ioctlsocket(m_sock, FIONBIO, &iMode);
 
    fd_set Write, Err;
    FD_ZERO(&Write);
    FD_ZERO(&Err);
    FD_SET(m_sock, &Write);
    FD_SET(m_sock, &Err);
 
    //Magic sleep for socket become ready to connect
    Sleep(10);
 
    // check if the socket is ready
    select(0, NULL, &Write, &Err, &timeout);            
    if(FD_ISSET(m_sock, &Write)) 
    {
        if(m_pLogger)
            m_pLogger->Log(logger::LL_OK, L"Successfully connected to SoIP device: %S port: %i",
                            inet_ntoa(devSoIP_addr.sin_addr),m_lPort);
        setsockopt(m_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
        setsockopt(m_sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));      
 
        return true;
    }
    else
    {
        int res = WSAGetLastError ();
        if(m_pLogger)
            m_pLogger->Log(logger::LL_ERROR, L"Failed to connect to SoIP device: %S  port: %i",
                            inet_ntoa(devSoIP_addr.sin_addr),m_lPort);
        Close();
        return iRes;
    }
 
}
Добавлено через 26 минут
Вру, при первой реинициализации TCP встает сразу практически. После второй - приходится очень долго ждать.
Реинициализации делаю последовательно с промежутком секунд в 15-30.

Добавлено через 2 минуты
Собственно засек по времени - почему то соединяется через минуту после предыдущего соединения.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
01.02.2016, 12:15
Цитата Сообщение от Leardjiny Посмотреть сообщение
Собственно засек по времени - почему то соединяется через минуту после предыдущего соединения.
как закрывается соединение на серверной и клиентской сторонах?
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
01.02.2016, 12:35  [ТС]
Со стороны клиента

C++
1
2
3
4
5
6
7
8
9
void CSoIPInterface::Close()
{
    if (m_sock != INVALID_SOCKET)
    {
        shutdown(m_sock, SD_BOTH);
        closesocket(m_sock);
        m_sock = INVALID_SOCKET;
    }
}
Со стороны сервера честно говоря не уверен - сервером выступает устройство MOXA NPort 5150. В ее настройках я подобного параметра не увидел.

Добавлено через 2 минуты
Есть параметр TCP alive check timeout. И у него пределы 1-99 мин. Но там выставлено 7, а реконнект ждет 1 мин. Поэтому думаю что это не то.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
01.02.2016, 14:50
setsockopt
Цитата Сообщение от Leardjiny Посмотреть сообщение
C++
1
setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
успешно прошло?

Добавлено через 45 секунд
Цитата Сообщение от Leardjiny Посмотреть сообщение
Со стороны сервера честно говоря не уверен -
ну хотя новое соединение должно быстро подниматься, там со стороны сервера просто accept ну или дебажьте и ищите ф-цию на которой зависает
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
01.02.2016, 15:00  [ТС]
Цитата Сообщение от aLarman Посмотреть сообщение
setsockopt
Сообщение от Leardjiny
C++Выделить код
1
setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
успешно прошло?
На опцию не ругается. Но она ни на что не влияет в данной ситуации, т.е. что с ней, что без нее - соединение в любом случае устанавливается через минуту.

Собственно не проходит условие
C++
1
 if(FD_ISSET(m_sock, &Write))
тут при помощи WSAGetLastError все равно ничего не узнаешь (она все равно 0 возвращает), а остальные функции проходят без ошибок.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
01.02.2016, 23:35
Цитата Сообщение от Leardjiny Посмотреть сообщение
// check if the socket is ready select(0, NULL, &Write, &Err, &timeout);
ну для начала надо проверить что она возвращает 1, а не -1 в случае ошибки или 0 в случае если таймаута, а во вторых передавать туда надо в качестве первого параметра сокет+1 т.е m_sock+1, такова логика вещей)
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
02.02.2016, 10:05  [ТС]
Т.е. как то так?

C++
1
int res = select(0, NULL, &Write+1, &Err+1, &timeout);
и потом res проверять? или +1 куда то в другое место добавить надо
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
02.02.2016, 10:44
C++
1
int res = select(m_sock+1, NULL, &Write, &Err, &timeout);
и да res проверять)
1
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
02.02.2016, 10:48  [ТС]
Понял, спасибо)) Буду пробовать сейчас, что-то забыл на эту функцию проверку добавить.
0
50 / 49 / 10
Регистрация: 24.01.2010
Сообщений: 225
04.02.2016, 16:18
и ещё...
в строке 190, у Вас будет вылет в случае коллизий в сети, ударных нагрузок на сервак, при потере пакетов в сети и прочей фигни из реальной жизни.

Причина банальна - в TCP нет пакетной передачи(для клиента сокета, коим Вы и являетесь). И иногда ваша длина принятых данных будет равняться меньше чем 128 байт...Редко но будет...

чтоб было понятнее...В TCP возможно следующая картина:
клиент отправляет 1000+300+500+200 байт
сервер получает 100+1800+50+50
прочувствуйте ситуацию...

удачи, она Вам потребуется
(круглый)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.02.2016, 16:18
Помогаю со студенческими работами здесь

Как через UDP сокет соединить трёх клиентов без сервера?
Люди подскажите как через UDP сокет соединить трёх клиентов без сервера

Материнка 775 сокет и процессор 771 сокет, Совместимость
Ребят помогите пожалуйста, попробовал разобраться Сам и только запутался больше... Вообщем имеется материнка g31t-m rev 1.0 вот ссылка...

4 планки Apacer DDR3 по 4Gb/1333MHz от старой МВ сокет 775 могу ли я их использовать на сокет 2011
недавно решил перейти с LGA775 на LGA2011. Финансы урезаны поэтому пока приобрёл только процессор Intel Core i7 - 3820 oem, 3.60GHz/ 10 MB/...

UDP сокет. Ошибка в программе.
Здравствуйте. Здесь я приведу фрагмент своей программы, в который закралась ошибка. В нём описано, как сервер, используя протокол UDP,...

Производительность Try-Catch в Сокет UDP
Приветствую, есть такая конструкция. IPEndPoint Address = new IPEndPoint(IPAddress.Parse(Ip), (int)Port); Socket = new...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru