Socket programming: unable to connect across network

Hi:

I have a laptop and I'm doing some socket programming on it.
I want to write a server listening on a port and serve requests from anyone who connects to me. Ideally, this experiment should take place across two independent hosts in two independent networks. However, since I've got only one machine, I'll run the server and the client on the same machine. But I'll not use the 127.0.0.1 or 192.168.1.x. Instead, I'll use my wan address so that the communication should first go to the deep internet and then come back to my machine. Correct me if my idea is wrong.

Assume my wan address is 111.111.111.256 (intentionally made illegal, you may replace it with your own wan address for experiment).


I've made sure the majority of the client/server programs should work perfectly. Please may I have your attention to
1
2
rec_addr.sin_port = htons(9734);
	rec_addr.sin_addr.s_addr = inet_addr("111.111.111.256");
? These are the places where I have questions.


Below is the code for server:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
using namespace std;


#include <sys/socket.h>
#include <sys/types.h>
//#include <sys/un.h>
#include <unistd.h>
#include <cstdlib>

#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
	// create socket file for two way communication
	int reception = socket(AF_INET, SOCK_STREAM, 0);//domain, type, protocol

	// bind created socket file with address
	sockaddr_in rec_addr;
	rec_addr.sin_family = AF_INET;
	rec_addr.sin_port = htons(9734);
	rec_addr.sin_addr.s_addr = inet_addr("111.111.111.256");
	
	bind(reception, (sockaddr *)&rec_addr, sizeof(rec_addr)); // socket, &address, addr_len

	// listen on socket file for connection
	listen(reception, 5);

	// accept connections
	while(true)
	{
		cout << "Server is waiting ...\n";

		sockaddr_in caddr;
		unsigned int clen = sizeof(caddr);
		int tube = accept(reception, (sockaddr *) &caddr, &clen);
		if(tube < 0)
		{
			exit(1);
		};

		cout << "Connection established with client ... \n\n";

		char rbuf [50];
		int act_rsize = read(tube, rbuf, sizeof(rbuf));
		cout << "received: " << rbuf << endl;
		cout << "act_rsize = " << act_rsize << endl << endl;

		char wbuf [] = "Hello, client.";
		int act_wsize = write(tube, wbuf, sizeof(wbuf));
		cout << "sent: " << wbuf << endl;
		cout << "act_wsize = " << act_wsize << endl << endl;

		close(tube);
	};


	return 0;
};



Below is the code for client:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
using namespace std;

#include <sys/types.h>
#include <sys/socket.h>
//#include <sys/un.h>
#include <cstdlib>
#include <unistd.h>

#include <arpa/inet.h>
#include <netinet/in.h>

int main()
{
	// create socket
	int sock = socket(AF_INET, SOCK_STREAM, 0);

	// create target socket address 
	sockaddr_in addr;
	addr.sin_port = htons(9734);
	addr.sin_addr.s_addr = inet_addr("111.111.111.256");
	addr.sin_family = AF_INET;

	// connect with server's socket
	int res = connect(sock, (sockaddr *) &addr, sizeof(addr));

	if(res == -1)
	{
		exit(1);
	};


	// read/write to local socket for communication
	char wbuf [] = "Hi This is client.";
	int act_wsize = write(sock, wbuf, sizeof(wbuf));
	cout << "sent: " << wbuf << endl << act_wsize << " bytes"<< endl << endl;

	char rbuf[50];
	int act_rsize = read(sock, rbuf, sizeof(rbuf));
	cout << "received: " << rbuf << endl << act_rsize << " bytes" << endl << endl;
	


	close(sock);

	return 0;
};



Post-compilation work:
What I do is, I first launch server; then I open another terminal and run client. But it seems both the server and the client gets stuck.

I made sure the port 9734 is available.


Could you please enlighten me what's the problem?

Thanks a lot!
Anyone? Please ...
Shouldn't the server program only have to specify the port it wants to listen on? If the server needs to specify an IP address, then I would think it would specify localhost. Also, make sure that your firewall will allow connections through port 9734.
Last edited on
You should check for errors and report them to the console, then it should tell you what is going wrong:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstring>
#include <cerrno>

// ...

if(bind(ss, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1)
{
    std::cout << strerror(errno) << '\n';
    exit(1);
}

if(listen(reception, 5) == -1)
{
    std::cout << strerror(errno) << '\n';
    exit(1);
}

// ... etc ...
Last edited on
Hi all:

I've found the problem lies in my router doing Network Address Translation.
I'm sitting behind a router, and I'm trying to make my connection travel through the WAN and come back.

I'm still exploring potential solutions. I'll post back later.
In the meantime, please share with me your suggestions. Thanks a lot!
Did you open the port and forward to the local IP of the system running the server? If the server is listening on the external address and the client attempts to access the external IP I dont believe NAT will be an issue.
@naraku9333:
Thank you very much for the reply.
I've resolved the issue. I configured my router to do port forwarding for my virtual server with lan address of 192.168.1.100 at port 9734. In addition, I changed the server's code a bit (Thanks to shacktar for pointing out the INADDR_ANY issue):
1
2
rec_addr.sin_port = htons(9734);
rec_addr.sin_addr.s_addr = htonl(INADDR_ANY);// instead of inet_addr("111.111.111.256"); 


And these changes make it work.


Now, naraku9333, I actually agree with your comment
If the server is listening on the external address and the client attempts to access the external IP I dont believe NAT will be an issue.


Therefore, I did two experiments:
1, I didn't configure the virtual server on my router(i.e. make the router do the port forwarding), the programs didn't connect;
2, I configured the virtual server on my router, but didn't change the code in my server (i.e. keep the external ip address; didn't change it to INADDR_ANY), the programs didn't connect either.


This is a bit confusing to me. I'm not very clear what role the piece of server code
1
2
rec_addr.sin_port = htons(9734);
rec_addr.sin_addr.s_addr = htonl(INADDR_ANY);// instead of inet_addr("111.111.111.256"); 

plays. I know the book reads, this means any address can connect to the server. However, I don't understand how it works. From my prior knowledge with Unix domain socket, the address we bind with the server socket corresponds to a socket file that represents the actual socket. To migrate my understanding, I would think, the ip address we bind with the server's socket should represent the server's location in the wan. Why am I wrong? And what's wrong?

I hope you or someone else could enlighten me. Thanks in advance!

Last edited on
Topic archived. No new replies allowed.