Winsock 绑定在同一个端口
Winsock binding on the same port
所以我最近决定通过使用我找到的指南并在网上搜索来涉足 winsock 和网络编程,但是我 运行 遇到了一个我不太确定应该如何解决的问题.
我正在尝试制作一个非常简单的聊天系统,我有一个可用的服务器程序和客户端程序,如果我只在客户端上使用(将消息发送回同一个客户端)它似乎可以工作非常好。当我尝试连接多个客户端时出现问题。我从 WSAgetlasterror 收到错误 10048,它似乎是绑定函数的来源,更具体地说,我试图在同一个端口上绑定两次(每个客户端一次)。在 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();}
服务器中必须有 1 个线程专用于接受新连接。
该进程侦听新连接并为该连接分配一个新端口(在服务器中),使默认端口可用于新连接。
在服务器中,您将随时打开 N+1 个套接字端口,其中 N 是服务器拥有的客户端数量,1 是侦听新连接的套接字。
看看这个:
http://www.codeproject.com/Articles/7785/Single-Server-With-Multiple-Clients-a-Simple-C-Imp
所以我最近决定通过使用我找到的指南并在网上搜索来涉足 winsock 和网络编程,但是我 运行 遇到了一个我不太确定应该如何解决的问题.
我正在尝试制作一个非常简单的聊天系统,我有一个可用的服务器程序和客户端程序,如果我只在客户端上使用(将消息发送回同一个客户端)它似乎可以工作非常好。当我尝试连接多个客户端时出现问题。我从 WSAgetlasterror 收到错误 10048,它似乎是绑定函数的来源,更具体地说,我试图在同一个端口上绑定两次(每个客户端一次)。在 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();}
服务器中必须有 1 个线程专用于接受新连接。
该进程侦听新连接并为该连接分配一个新端口(在服务器中),使默认端口可用于新连接。
在服务器中,您将随时打开 N+1 个套接字端口,其中 N 是服务器拥有的客户端数量,1 是侦听新连接的套接字。
看看这个: http://www.codeproject.com/Articles/7785/Single-Server-With-Multiple-Clients-a-Simple-C-Imp