具有单个客户端的多个服务器(Winsock)

时间:2014-09-26 15:41:36

标签: visual-c++ winsock2

Scenerio:有几台服务器在监听,一台客户端会向网络上的所有计算机发送UDP广播,服务器也会回复。 (目标:获取服务器的所有IP地址)

以下是客户端代码:



    int main()
{
	struct sockaddr_in connectedSocket;
	int length=sizeof(connectedSocket);
	int iResult = 0, iOptVal = 0, nOptiontValue = 1;
	SOCKET Socket;

	char receiveBuffer[1000];
	char message[1000];

	//Clear the buffer by filling null, it might have previously received data
	memset(receiveBuffer,'\0', 1000);

	WSADATA wsa;
	//Initialise winsock
	printf("\nInitialising Winsock...\n");
	if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
	{
		printf("\nFailed. Error Code : %d",WSAGetLastError());
		exit(EXIT_FAILURE);
	}
	printf("\n.........Initialised.\n");

	//Create socket
	Socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (Socket == SOCKET_ERROR)
	{
		printf("Create a UDP socket failed with error = %d\n" , WSAGetLastError());
		exit(EXIT_FAILURE);
	}

	//Set socket options to broadcast
	iResult = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST,(char *) &iOptVal, sizeof (iOptVal));
	if(iResult == SOCKET_ERROR) 
	{
		printf("Set socket options failed with error = %d\n" , WSAGetLastError());
		exit(EXIT_FAILURE);
	}

	//Setup address structure
	memset((char *) &connectedSocket, 0, sizeof(connectedSocket));
	connectedSocket.sin_family = AF_INET;
	connectedSocket.sin_port = htons(PORT);
	connectedSocket.sin_addr.s_addr = INADDR_BROADCAST;

	while(1)
	{
		printf("\n\n\nEnter message : ");
		gets(message);

	  //send the message
		if (sendto(Socket, message,sizeof(message) , 0 , (struct sockaddr *) &connectedSocket, sizeof(connectedSocket)) == SOCKET_ERROR)
		{
			printf("\nsendto() failed with error code : %d" , WSAGetLastError());
			exit(EXIT_FAILURE);
		}

		printf("\nMessage Successfully sent to Server");
		// fflush(stdout);

		if (recvfrom(Socket, receiveBuffer, 1000, 0, (struct sockaddr *) &connectedSocket,&length) == SOCKET_ERROR)
		{
		   printf("\nrecvfrom() failed with error code : %d" , WSAGetLastError());
		   exit(EXIT_FAILURE);
		}

		printf("\nServer Says : ");
		printf(receiveBuffer,sizeof(receiveBuffer));

	}

	closesocket(Socket);
	WSACleanup();

	return 0;
}




当我运行时,我得到" sendto()失败,错误代码为:10013"。我查找winsock错误,它说"尝试以其访问权限禁止的方式访问套接字。一个例子是使用sendto的广播地址而没有使用setsockopt(SO_BROADCAST)设置广播权限。"但我将sockopt设置为SO_BROADCAST。谁能告诉我为什么会这样?

1 个答案:

答案 0 :(得分:-1)

您发布的代码的相关部分在这里:

int iResult = 0, iOptVal = 0, nOptiontValue = 1;

...

//Set socket options to broadcast
iResult = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST,(char *) &iOptVal, sizeof (iOptVal));
if(iResult == SOCKET_ERROR) 
{
    printf("Set socket options failed with error = %d\n" , WSAGetLastError());
    exit(EXIT_FAILURE);
}

请注意变量 iOptVal 已初始化为 0。它没有在其他任何地方修改。然后将该变量传递给 setsockopt() 函数。

这会将 SO_BROADCAST 选项设置为 FALSE(这是默认值,因此实际上它不会更改该值) .

设置它是不够的。您必须将其设置为正确的值。这将是 TRUE

您可以通过将变量初始化为 1 而不是 0 来实现。