CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Sep 2008
    Posts
    119

    bind() binds server socket with local IPv6/Port....How Can I Make It bind() on IPv4?

    I got a weird problem. I coded a server. Works good, but it only binds the port to the local IPv6 .... So when the client enters the target external IP (Usually IPv4)/port. Client will be able to connect to the listening port that is through IPv4 only...

    For example, i made my server binds on port 4443 on the local machine...

    I check netstat -an, i get

    Proto Local Address Foreign Address State
    TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
    TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
    TCP 0.0.0.0:1025 0.0.0.0:0 LISTENING
    TCP [::]:135 [::]:0 LISTENING
    TCP [::]:445 [::]:0 LISTENING
    TCP [::]:1025 [::]:0 LISTENING
    TCP [::]:4443 [::]:0 LISTENING

    ports 135, 445, and 1025 will respond to client who connects to it through IPv4 or IPv6. 4443 will only respond to client who connects to it through IPv6. So for a client to connect on the server port 4443, it (client) must enter IPv6 for the target so 4443 can respond. Otherwise, connection will fail as you see that 4443 is not included among IPv4! I hope you get my point.....Weird problem! ..... On linux, everything works fine, but on Vista things did not go as it should be....

    I hope somebody can provide some help...

  2. #2
    Join Date
    Oct 2005
    Location
    Minnesota, U.S.A.
    Posts
    680

    Re: bind() binds server socket with local IPv6/Port....How Can I Make It bind() on IP

    Post some code.

  3. #3
    Join Date
    Sep 2008
    Posts
    119

    Re: bind() binds server socket with local IPv6/Port....How Can I Make It bind() on IP

    Not a perfect code, i just did it to practice on it roughly, so the code uses mixture of C/C++ .... It worked under linux...Once i ported into windows, i faced the problem i mentioned above...

    Code:
    #include<iostream>
    #include<string>
    #include<sstream>
    #include"Winsock2.h"            //VC++
    #include<Ws2tcpip.h>            //VC++
    #include<Winerror.h>            //VC++
    using namespace std;
    
    #define BACKLOG 2    	// how many pending connections queue will hold
    #define MAX_DATA 1024	//maximum bytes that could be sent or received 
    
    //describe the program
    void progDesc()
    {
    	cout<<"This server listens for a connection from client, and waits\n";
    	cout<<"some data from client. Server echos back same message to client."<<endl;
    }
    
    //get sockaddr, IPv4 or IPv6:
    void *get_client_addr(struct sockaddr_storage *clientInformation)
    {
    	void *addr;
    	
    	if (clientInformation->ss_family == AF_INET) {
    		struct sockaddr_in *ipv4 = (struct sockaddr_in *)clientInformation;
    		addr = &(ipv4->sin_addr);
    		return addr;
    	}else{
    		addr = &( ((struct sockaddr_in6 *)clientInformation)->sin6_addr );
    		return addr;
       	}
    }
    
    
    u_short get_client_port(struct sockaddr_storage *clientInformation)
    {
    	u_short portNumber;
    	
    	if (clientInformation->ss_family == AF_INET) {
    		struct sockaddr_in *ipv4 = (struct sockaddr_in *)clientInformation;
    		portNumber = ipv4->sin_port;
    		return portNumber;
    	}else{
    		struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)clientInformation;
    		portNumber = ipv6->sin6_port;
    		return portNumber;
       	}
    }
    
    int main()
    {
    
    	SOCKET serverSockD;         
    	SOCKET clientSockD;      
    	struct addrinfo hints;     
    	struct addrinfo *servInfo;  
    	struct sockaddr_storage clientInfo; 
    	int clientInfo_size; 
    	char *listenPort = new char[10];  
    
        WORD wVersionRequested;
        WSADATA wsaData;
        int err;
    
        wVersionRequested = MAKEWORD(2, 2);
    
        err = WSAStartup(wVersionRequested, &wsaData);
        if (err != 0) {
            printf("WSAStartup failed with error: %d\n", err);
            return 1;
        }
    
    	
    	cout<<"Choose a port to listen on: ";
    	cin>>listenPort;
    
    	//set size of hints to zero
    	memset(&hints, 0, sizeof hints);
    
    	hints.ai_family = AF_UNSPEC;
    	hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE;  
    
    	int status = getaddrinfo(NULL, listenPort, &hints, &servInfo);
    	
    	if(status == -1)
    	{
    		fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    		WSACleanup();
    		return 1;
    	}
    
    	serverSockD = socket(servInfo->ai_family, servInfo->ai_socktype, servInfo->ai_protocol);
    
    	if(serverSockD == INVALID_SOCKET )
    	{
    		cout<<"Error: failed to create a socket.\n";
    		closesocket(serverSockD);
    		WSACleanup();
    		return 2;
    	}
    	
    	//****bind socket to ip/port
    	if(bind(serverSockD, servInfo->ai_addr, servInfo->ai_addrlen) == SOCKET_ERROR) 
    	{
    		perror("server: bind");
    		closesocket(serverSockD);
    		WSACleanup();
    	    return 3;
    	}
    
    	//****socket should be listening - open
    	if(listen(serverSockD, BACKLOG) == SOCKET_ERROR) 
    	{
    	    perror("listen");
    		closesocket(serverSockD);
    		WSACleanup();
    	    return 4;
    	}
    
    	cout<<"waiting for a connection ... "<<endl;
    
    	clientInfo_size = sizeof clientInfo;
    	int bytes_received;
    	char data[MAX_DATA];
    	char printableClientIP[INET6_ADDRSTRLEN];
    	void *clientIP;
    	u_short portNum;
    
    	//keep listening until you kill the server process
    	while(1)
    	{
    		clientSockD = accept(serverSockD, (struct sockaddr *)&clientInfo, &clientInfo_size);
    
    		if(clientSockD == INVALID_SOCKET )
    		{
    			cout<<"ERROR: "<<WSAGetLastError()<<endl;
    			closesocket(clientSockD);
    			closesocket(serverSockD);
    			WSACleanup();
    	   		return 5;
    		}
    
    		clientIP = get_client_addr(&clientInfo);
    		portNum =  get_client_port(&clientInfo);
    		inet_ntop(clientInfo.ss_family, clientIP, printableClientIP, sizeof printableClientIP);
    		u_short portHostByte = ntohs(portNum);
         
    		printf("New Client connected from port no. %d and IP %s\n", portHostByte, printableClientIP);
    
    		bytes_received = 1;
    
    		while(bytes_received > 0)
    		{
    			bytes_received = recv(clientSockD, data, MAX_DATA, 0);
    
    			if(bytes_received > 0)
    			{
    				send(clientSockD, data, bytes_received, 0);
    				data[bytes_received] = '\0';
    				printf("Sent mesg: %s", data);
    			}
    
    		}
    
    		printf("Client disconnected\n");
    
    		closesocket(clientSockD);
    	}
    
    	closesocket(serverSockD);
    
    	delete[] listenPort;
    
    	freeaddrinfo(servInfo);
    
        WSACleanup();
    
    	return 0;
    }

  4. #4
    Join Date
    Oct 2005
    Location
    Minnesota, U.S.A.
    Posts
    680

    Re: bind() binds server socket with local IPv6/Port....How Can I Make It bind() on IP

    Change

    Code:
    hints.ai_family = AF_UNSPEC;
    to

    Code:
    hints.ai_family = AF_INET;
    to do IPV4. With AF_UNSPEC, then things will connect with the highest numbered family protocol which happens to be IPV6 with Windows.

    -Erik

  5. #5
    Join Date
    Sep 2008
    Posts
    119

    Re: bind() binds server socket with local IPv6/Port....How Can I Make It bind() on IP

    Haa! Duh, how come i did not realize it.... I will check it out later & let you know....
    Your help is much appreciated...

  6. #6
    Join Date
    Sep 2008
    Posts
    119

    Re: bind() binds server socket with local IPv6/Port....How Can I Make It bind() on IP

    Worked....Many thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured