Так что я недавно решил немного поработать в winsock и сетевом программировании, используя руководство, которое я нашел и искал в сети, но у меня возникла проблема, которую я не совсем уверен, как я должен решить ,Перехват Winsock на том же порту
Я пытаюсь создать очень простую систему чата, у меня есть рабочая программа сервера и клиентская программа, и если я использую только клиент (отправка сообщения обратно одному клиенту) Кажется, что он отлично работает хорошо. Проблема возникает, когда я пытаюсь подключить несколько клиентов. Я получаю сообщение об ошибке 10048 из WSAgetlasterror и, похоже, это функция связывания, которая является источником, а более конкретно тот факт, что я пытаюсь связать на одном и том же порту дважды (один раз для каждого клиента). Оглядываясь на msdn и форумы, кажется, что можно обойти эту проблему, используя setsockopt, но я не совсем уверен, какие изменения я должен внести, а также если это самое умное решение.
Я имею в виду, что я хочу, чтобы клиенты подключались к одному порту, не так ли? Как еще клиентская программа знает, к чему подключиться? Или я просто что-то пропустил? Как я уже сказал, у меня нет предыдущего опыта работы с winsock или любым другим сетевым программированием, поэтому я мог бы делать что-то глупо.
int listenOnPort(int portno, SOCKET& reciever, SOCKET s){
int error = WSAStartup(0x0202, &w);
if (error)
{
cout << "Error starting WSA";
return false; //for some reason we couldn't start Winsock
}
if (w.wVersion != 0x0202) //Wrong Winsock version?
{
cout << "Wrong Winsock version";
WSACleanup();
return false;
}
SOCKADDR_IN addr; // The address structure for a TCP socket
addr.sin_family = AF_INET; // Address family
addr.sin_port = htons(portno); // Assign port no to this socket
//Accept a connection from any IP using INADDR_ANY
//You could pass inet_addr("0.0.0.0") instead to accomplish the
//same thing. If you want only to watch for a connection from a
//specific IP, specify that //instead.
addr.sin_addr.s_addr = htonl(INADDR_ANY);
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Create a socket
if (s == INVALID_SOCKET)
{
cout << "Couldn't create the socket";
return false; //Don't continue if we couldn't create a //socket!!
}
if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
{
//We couldn't bind (this will happen if you try to bind to the same
//socket more than once)
cout << "Error binding the socket";
return false;
}
//Now we can start listening (allowing as many connections as possible to
//be made at the same time using SOMAXCONN). You could specify any
//integer value equal to or lesser than SOMAXCONN instead for custom
//purposes). The function will not //return until a connection request is
//made
listen(s, 1);
reciever = accept(s, NULL, NULL);
cout << "connection established\n\n";
//Don't forget to clean up with CloseConnection()!}
int main(){
e = WSAGetLastError();
listenOnPort(1337, r1, s1);
cout << "First Client connected\n\n";
e = WSAGetLastError();
listenOnPort(1338, r2, s2);
cout << "Second Client connected\n\n";
e = WSAGetLastError();
std::thread com1(communicate, r1, r2);
std::thread com2(communicate, r2, r1);
com1.join();
com2.join();
//system("pause");
closeConnection();}
Для TCP вы создать только один единственный пассивный сокет и привязать его к порту. Все клиенты подключаются к одному и тому же порту, а затем вы принимаете эти новые соединения в этом одиночном пассивном сокете. Вам не нужно открывать один пассивный сокет для каждого клиента. –