...
CreateListenSocket();
Accept();
...
...
void MCServer::CreateListenSocket() {
// Create a socket and bound it as listening socket
_ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (_ListenSocket == INVALID_SOCKET) {
cerr << "Can't create a socket!\tError >> " << WSAGetLastError() << endl;
}
// Bind the ip address and port to a socket
sockaddr_in hint = { 0 };
hint.sin_family = AF_INET;
hint.sin_port = htons(_port);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(_ListenSocket, (sockaddr*)&hint, sizeof(hint));
// Tell Winsock the socket is for listening
listen(_ListenSocket, SOMAXCONN);
cout << "Listen socket ready\t\tsocket: " << _ListenSocket << endl;
}
...
void MCServer::Accept() {
_Client = accept(_ListenSocket, 0, 0); //<<<<<<<<<< PROBLEM
}
...
class MCServer {
...
private:
int _port;
char* _buf;
int _size = 4096;
SOCKET _ListenSocket;
SOCKET _Client;
fstream _file;
string _time;
string _skt;
...
При запуске сервера _Client получает верное значение. 128 или 126 или 132 например. Дойдя до
_Client = accept(_ListenSocket, 0, 0);
честно ждет входящего соединения. Когда клиент стучится - срабатывает. Затем, когда работа с этим клиентом завершена, сервер закрывает сокет и снова вызывает
...
CreateListenSocket();
Accept();
...
Но, дойдя во второй раз до
_Client = accept(_ListenSocket, 0, 0);
_Client присваивается космическое число... Типо 99895919816189 и accept() принимает соединение без входящего клиента, когда должен по идее ждать реальный вызов. Но клиент еще не коннектился. В чем дело?
Нашел ошибку и хочу поделиться. Надеюсь, поможет кому-нибудь. Дебагером нашел проблему:
Возвращает -1 функция bind(_ListenSocket, (sockaddr*)&hint, sizeof(hint));
Читая MSDN, нашел решение.Необходимо настроить эту функцию:
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
setsockopt(_ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen);
теперь bind() может связывать сокеты, по которым уже передавались данные.
Но проблема не ушла. bind(), listen() и accept() работают так как надо. accept() уходит в ожидание как положено, но при новом входящем соединении не принимает его. Ничего не происходит. Нашел в итоге ошибку: Вот тут, в собственном методе:
void MCServer::Accept() {
_Client = accept(_ListenSocket, 0, 0); //<<<<<<<<<< PROBLEM
}
После назначения нового сокета клиенту я не закрываю "слушающий порт". И при повторном вызове метода
void MCServer::CreateListenSocket() {
// Create a socket and bound it as listening socket
_ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (_ListenSocket == INVALID_SOCKET) {
cerr << "Can't create a socket!\tError >> " << WSAGetLastError() << endl;
}
// Bind the ip address and port to a socket
sockaddr_in hint = { 0 };
hint.sin_family = AF_INET;
hint.sin_port = htons(_port);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(_ListenSocket, (sockaddr*)&hint, sizeof(hint));
// Tell Winsock the socket is for listening
listen(_ListenSocket, SOMAXCONN);
cout << "Listen socket ready\t\tsocket: " << _ListenSocket << endl;
}
я пытаюсь переназначить уже слушающий сокет не закрыв его должным образом.
Решение - либо закрывать "слушающий порт" после каждого accept() либо не пытаться создавать его заново. Повторный вызов метода CreateListenSocket();
ошибочен.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Мне нужно создать некий накопитель информаци к которому будет доступ разных приложений
Верные ли утверждения: 1Полная специализация есть для функций и классов 2