сокеты — WinSock rehost на том же порту не работает должным образом переполнение стека

У меня есть программа, и она прослушивает порт 200. После того, как к нему подключен клиент, все полученные от клиента данные записываются в std :: cout. Если при получении данных от клиента произойдет какая-либо ошибка, я бы хотел перезапустить хостинг.

ServerSocket sock;
while(true)
{
try
{
uint8 buff[1000];
std::cout << "hosting..." << std::endl;
sock.Host(port);

while(true)
{
size_t ret = sock.GetData(buff, 1000);
buff[ret] = '\0';
std::cout << buff << std::endl;
}
}
catch(const SocketException& se)
{
std::cout << se.What() << std::endl;
}
}

Первый раз подключаюсь к этому все нормально. Если я закрываю клиент, возникает SocketException (и, следовательно, начинается новый хостинг).

функция хоста:

    m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

m_address.sin_family = AF_INET;
m_address.sin_port = htons(port);
m_address.sin_addr.S_un.S_addr = INADDR_ANY;

int optval = 1;
setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(int));

int retval = bind(m_socket, reinterpret_cast<sockaddr*>(&m_address), sizeof(m_address));

if(retval == SOCKET_ERROR)
throw SocketException("bind() error", __FUNCTION__, WSAGetLastError());

retval = listen(m_socket, SOMAXCONN);

if(retval == SOCKET_ERROR)
throw SocketException("listen() error", __FUNCTION__, WSAGetLastError());

m_socket = accept(m_socket, NULL, NULL);

if(m_socket == INVALID_SOCKET)
throw SocketException("accept() error", __FUNCTION__, WSAGetLastError());

Мне нужна строка setsockopt, потому что я хотел бы связать сразу после ошибки (и последний хост-сокет находится в состоянии TIME_WAIT?). Без setsockopt у меня есть ошибки bind ().
Поэтому я использую setsockopt, и он позволяет мне без проблем размещать порт. Однако, когда я снова запускаю клиент и пытаюсь подключиться к хосту ошибок нет и я могу отправить данные еще раз.
Однако программа не принимает входящие соединения (он все еще застрял при принятии (m_socket, NULL, NULL); линия ожидает входящего соединения). Я предполагаю, что клиент может как-то подключиться к старому сокету. Это возможно?

(нота:
Если я добавлю WSACleanup ();
WSAStartup (MAKEWORD (2, 2), &m_wsaData);
линии к функции хоста, затем все работает как предполагалось. Понятия не имею почему.
WSACleanup (); WSAStartup (MAKEWORD (2, 2), &m_wsaData); выручает меня только в моем примере программы, которую я сделал, чтобы исследовать эту проблему. В оригинальной программе эта 2 строки не работает.)

0

Решение

Ты звонишь bind() а также listen() для каждого соединения. Ты должен сделать bind() а также listen() один раз, когда ваш сервер запускается, а затем позвонить только accept() несколько раз.

Также, чтобы сделать это правильно, вы должны создать новую ветку для каждого accept() позвоните, в противном случае люди смогут DOS вашего сервера, просто открыв соединение с ним, а затем ничего не отправляя.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]