Jump to content
  • Advertisement
Sign in to follow this  
mmitica

boost::asio socket client GPRS modem on Linux

This topic is 3169 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am facing a problem writing a c++ socket client application that will connect to a server and send some data using a GPRS modem. I have a small embedded computer with a 500Mhz ARM processor, running Linux. It has the following: - a Network adapter (eth0: IP 10.10.10.147) - a GSM/GPRS modem that automatically registers and logs into the network (ppp0: IP: 172.28.96.28) Below is the output of the "ifconfig" -------------------------------------------------- eth0 Link encap:Ethernet HWaddr 00:50:C2:44:6B:9B inet addr:10.10.10.147 Bcast:10.10.10.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:41206 errors:1 dropped:0 overruns:0 frame:0 TX packets:466 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:4158407 (3.9 MiB) TX bytes:51851 (50.6 KiB) Interrupt:21 Base address:0x4000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) ppp0 Link encap:Point-to-Point Protocol inet addr:172.28.96.28 P-t-P:192.168.202.0 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:4 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:52 (52.0 B) TX bytes:58 (58.0 B) usb0 Link encap:Ethernet HWaddr 2E:0F:79:D7:F0:2E inet addr:10.99.99.99 Bcast:10.99.99.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) --------------------------- The client application is running on the computer mentioned above. For testing purposes I am using 2 server that listen for connection from this client: - one server in the same network as the eth0 interface (Server1_IP: 10.10.10.109) - another server visible in the vpn network via ppp0 interface (Server2_IP: 192.168.2.2) For testing the conectivity between the client computer and servers: Server1: /mnt/server/release # ping 10.10.10.109 PING 10.10.10.109 (10.10.10.109): 56 data bytes 64 bytes from 10.10.10.109: seq=0 ttl=128 time=2.142 ms 64 bytes from 10.10.10.109: seq=1 ttl=128 time=1.414 ms Server2: /mnt/server/release # ping -I ppp0 192.168.2.2 PING 192.168.2.2 (192.168.2.2): 56 data bytes 64 bytes from 192.168.2.2: seq=0 ttl=120 time=1136.668 ms 64 bytes from 192.168.2.2: seq=1 ttl=120 time=930.169 ms The "connect" part of the c++ client application loks like this: 1. Create a local boost endpoint to bind the client to: boost::asio::io_service m_io_service; tcp::socket* m_socket; std::string sAddr1 = "10.10.10.147"; boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(sAddr1.c_str()), 55003); m_socket = new tcp::socket(m_io_service); m_socket->open(boost::asio::ip::tcp::v4()); m_socket->set_option(boost::asio::socket_base::reuse_address(true)); m_socket->bind(ep); 2. Create the server endpoint std::string m_sIPAddress = "10.10.10.109"; boost::asio::ip::tcp::endpoint server_endpoint(boost::asio::ip::address::from_string(m_sIPAddress.c_str()), 8474); 3. Call async_connect m_socket->async_connect(server_endpoint, boost::bind(&CSocketClient::handle_connect, this, boost::asio::placeholders::error)); In this case everything works well. The connect call handler gets called and there is no error. The problem I am facing is when am I trying to bind the local client socket to the IP address of the ppp0 and trying to connect to Server2. The connect call never returns and the program hangs. What am I doing wrong? Maybe I do not correctly understand the architecture of boost::asio? If someone could help, I would really appreciate it. Thank you for your time.

Share this post


Link to post
Share on other sites
Advertisement
What happens if you just use telnet to try and connect to the server?

Although to be honest, connect *hanging* normally means some part of the handshake is vanishing -- it's not getting told to foff, but it's never seeing an ack either which usually means something's just binning all the packets.

Can you run tcpdump/wireshark on the interface and see any of the traffic at all?

Share this post


Link to post
Share on other sites
You either bind (as a server) or you connect (as a client) -- it sounds on your description as if you try to do both?

Also, I don't quite see how you can route to a 192.x private net, as your interface addresses are 172.x and 10.x. If you do a "route -n" what does it say?

Share this post


Link to post
Share on other sites
Thank you all for replying.

There is a route in order to reach the 192.168xx. As you can see the ping is responding.

My socket, is a client socket and I am trying to bind (as a client) in order to select a specific network card.
The idea is to implement a dual network card solution using GPRS modems.
The device will have 2 different GPRS cards and will first try to connect to Server1 using GPRS Module 1.If there is no answer, then will try to connect to Server2 using GPRS Module 2(GPRS Modules will have different IPs and will be in different networks with no route between them).

I may be facing a firewall issue here, but I am still checking.
I just wanted to know if the socket operations I was performing are correct?

1. create socket (client)
2. open socket
3. bind to one of the interfaces

Thank you for your time.

Share this post


Link to post
Share on other sites
Clients don't bind.


Client code;

1. socket() to make an fd.
2. possibly do name resolution.
3. connect() to the target
4. read/write

Server code;

1. socket() to make a suitable fd.
2. bind() to either a port or to a port/interface pair.
3. listen() to set the length of the queue
4. accept() to get incoming connections off the queue.
5 read/write to those sockets.


The way that the client picks which interface to use is entirely at the whim of the routing system in the OS.

Share this post


Link to post
Share on other sites
Thank you <Katie> and <hplus> for taking the time to answer my question.

I was making a mistake; most probably a beginner mistake, but I managed to find the answer. Basically my problem was forcing the client socket to use a specific network interface and I assumed that by binding the client I was forcing the system to use the interface with the specified IP for sending the traffic. I was wrong.
Long story short, here is a quote from one of the links below:

"
using bind() is quite wrong. bind() will control the source IP address placed within the packet IP header. It does not control which interface will be used to send the packet: the kernel's routing table will be consulted to determine which interface has the lowest cost to reach a particular destination. (*see note)

Instead, you should use an SO_BINDTODEVICE sockopt. This does two things:

Packets will always egress from the interface you specified, regardless of what the kernel routing tables says.
Only packets arriving on the specified interface will be handed to the socket. Packets arriving on other interfaces will not.
" answered Oct 6 '08 at 4:23 DGentry (stackoverflow.com)

Here are 2 web links that got me in the right direction:
1. http://stackoverflow.com/questions/172905/using-linux-how-to-specify-which-ethernet-interface-data-is-transmitted-on
2. http://tuxology.net/2008/05/15/forcing-connections-through-a-specific-interface/

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!