Where to start with TCP communications? - networking

I'm getting ready to attempt my first project involving networked communications. This is just a tinker-toy app with the purpose of self-teaching - nothing mission-critical here. I will need two nodes to communicate with each other. One will be an Android platform, so I will be using Java. The other node will be a RaspberryPi running Debian Linux. While I COULD use Java on this end as well and maybe just use RPC, what I would LIKE to do is develop my own little implementation-agnostic TCP/IP "protocol" for the two to communicate, and let the each implement it however works best. What I mean by "protocol" is I want a standard set of messages to be passed back and forth, along with some values with each. E.g.:
"Protocol" Definition:
MESSAGE TYPE A (Float arg, Int arg)
MESSAGE TYPE B (Int arg)
MESSAGE TYPE C (Int arg, String arg, Int arg)
An example "conversation":
Node 1 Node 2
A(5.4, 4) --->
B(6) --->
<---- C(3, 'Hello', 0xFF)
B(5) --->
<---- A(43.0, 16)
So my questions are:
(1) Does the above even make sense? Do I need to clarify my intent? Provide more info? This is my first forray into networked communication between two running programs, so I may be way off-base in what I'm asking for. If I'm approaching this the wrong way, I'd be happy for better recommendations.
(2) How would I go about this? Do I just stuff one long string into a TCP packet? Is there a better way?
Thanks!

You only need to fill a buffer with the data you want and then learn how to open and send data through a TCP socket. The kernel will handle how to arrange the payload and how to control the TCP stream. On the server end, you must learn how to listen on a TCP socket and read incoming data.

Socket Programming is the word you should be searching for.

Related

recvfrom does not receive anything from the client, but the client is sending the info

So I wanted to make sure I am not missing something and I have the concepts clean in my head.
This is the part of the code I have:
UDP_Msg mensajeRecibidoUdp;
struct sockaddr_in c_ain;
sock_udp=socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in c_ain;
socklen_t tam_dir;
while(1)
{
if(recvfrom(sock_udp, &mensajeRecibidoUdp, sizeof(UDP_Msg), 0,
(struct sockaddr*) &c_ain, &tam_dir) <0)
....
The problem is that it waits for a message to arrive. And the message is sent, but this code does not get anything, it doesn't unfreeze.
It's a simple exercise, and the client is already built. It gets the port from a file, then sends a UDP_Message that is a struct with a couple ints and an array (the client already knows the IP and port).
I thought the way I handle the buffer could be wrong, but every example I've seen uses it like that. I also thought that the c_ain variable might needed to be initialized, but that's not the case if I understand it properly. So I don't get why the process gets... blocked, not sure what's the proper word, and since a lot of time passes by, an alarm goes off and the process gets killed (because it should have got info and keep with the code but it did not).
I can add lots of other info, I tried to keep it short. I kind of know that call is the one that isn't working properly because of how it behaves when I run the client-server thingy.
Edit: Bind:
bzero((char*)&dir_udp_serv,sizeof(struct sockaddr_in));
dir_udp_serv.sin_family=AF_INET;
dir_udp_serv.sin_addr.s_addr=inet_addr(HOST_SERVIDOR);
dir_udp_serv.sin_port=0;
fprintf(stderr,"SERVIDOR: Asignacion del puerto servidor: ");
if(bind(sock_udp,
(struct sockaddr*)&dir_udp_serv,
sizeof(struct sockaddr_in))<0)
{
fprintf(stderr,"ERROR\n");
close(sock_udp); exit(1);
}
Second edit: I just realized I have two binds in the code. The idea is I create two connections on the same server, one for UDP and one for TCP. So I made the same steps for both UDP and TCP. From the answer I got I realize that might be wrong. Would it be only 1 bind per socket, even if I create two sockets, one for UDp and one for TCP?
The above does not seem to be the case.
Also, I don't know what more details should I add, but the server and client are both on the same computer so their address are both 127.0.0.1, but that's expected and I believe does not change anything as to why the server does not get the info sent from the client.
Ask yourself: on which port do your clients send their messages? Where is that port in your server code? Nowhere. You forgot to bind your local socket to your local address (and port) :
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr("0.0.0.0");
local.sin_port = htons(PORT); // Now the server will listen on PORT.
if(bind(sock_udp, (struct sockaddr*)&local, sizeof(local)) < 0){
perror("bind");
exit(1);
}
// Now you may call recvfrom on your socket : your server is truly listening.
Note that you only need to bind once. No need to put this in a loop.
Allright not sure if this is the place, but the answer to my own question was one expected: The server was listening in a port, and the client was sending to a different one. That was because of the way the port assigned was sent to the client: in my case, without transform it to network format (ntohs()), so when the client did htons(), the number was a completly different one.

Better understand of sockt - is it ok to use the same raw socket to send data from different interfaces?

I read raw socket tutorial in order to implement my own bridge (i capture package from one side and send them to the other interface by raw socket). I am coming from Java world, so low level programming is strange to me, so forgive me for my ignorance.
I implement a bridge, so I need to send traffic from A to interface B and vice versa.
I created a single raw socket and I used it to send data to both servers by 2 different interfaces.is there any reason to why not use the same socket in order to send from interface A or B? I am asking if it's a good practice? problems and etc
It will be great if you can clarify to me how socket is not binded to a physical interface in the underline. this is the reason that it seems strange to me that the same raw socket use to send data for different interfaces.
There is no problem to use the same raw socket for two different interfaces. the use in the specific interface is done when you call to send.

in Vxworks, under what circumstances Send() api will get stuck or take more time?

i am using two m/c A and B, both are having same vxworks image as well as hardware. but only change is application. suppose M/c A is server and M/c B is client. while communication over ethernet client M/c is not able send the data. it's getting stuck send() and task state will be Pend.
wState = send(vstCCEUSerSocket.wCCEUAcceptFD,(char* )vstCCEUAppTask.rgubyCCEUTxPkt,sizeof(vstCCEUAppTask.rgubyCCEUTxPkt),0);
/*logMsg("\nTrmtd = %d\t",wState);*/
if(wState == ERROR)
{
perror("write");
Close the Fd
}
From the VxWorks OS Libraries API Reference
Page 497/498 you can find info about the connect() but there's also a connectWithTimeout()
Page 1203/1204 you might find some interesting items for TCP sockets. For example the KEEP_ALIVE
If you rely on a quick connection time, and you want to keep control you can combine connectWithTimeout with the keep alive.
It can take another day for me to recall old code to check how I ever solved this in one of my projects.
VxWorks 5.5 Network Programmers Guide - Stream Sockets

WSAECONNABORTED when using recv for the second time

I am writing a 2D multiplayer game consisting of two applications, a console server and windowed client. So far, the client has a FD_SET which is filled with connected clients, a list of my game object pointers and some other things. In the main(), I initialize listening on a socket and create three threads, one for accepting incoming connections and placing them within the FD_SET, another one for processing objects' location, velocity and acceleration and flagging them (if needed) as the ones that have to be updated on the client. The third thread uses the send() function to send update info of every object (iterating through the list of object pointers). Such a packet consists of an operation code, packet size & the actual data. On the client I parse it, by reading first 5 bytes (the opcode and packet size) which are received correctly, but when I want to read the remaining part of the packet (since I now know the size of it), I get a WSAECONNABORTED (error code 10053). I've read about this error, but can't see why it occurs in my application. Any help would be appreciated.
The error means the system closed the socket. This could be because it detected that the client disconnected, or because it was sending more data than you were reading.
A parser for network protocols typcally needs a lot of work to make it robust, and you can't tell how much data you will get in a single read(), e.g. you may get more than your operation code and packet size in the first chunk you read, you might even get less (e.g. only the operation code). Double check this isn't happening in your failure case.

How do I make an outgoing socket to a SPECIFIC network interface?

I have a server with two different network interfaces, each with a different IP address. How can I create a socket so it'll go out a specific IP address?
I'd prefer a python example, but the question is language agnostic, so shoot away.
EDIT: Please don't give me "You can't" as an answer. I mean, it is a computer. I can do anything I like to it, for example - I can programatically disable the one interface I don't want on the fly. I'm looking for something prettier.
You can certainly bind a socket to a specific device.
I don't know how to do it in python, but using the berkeley socket api (in C) you need to call setsockopt(), using the option SO_BINDTODEVICE.
You pass in an interface descriptor, which is of type struct ifreq. Ideally you would get the contents of the interface descriptor by using ioctl(), and requesting SIOCGIFINDEX - passing the name of the interface (eg. eth0) as an argument.
edit: Just did a quick search and found this documentation of the socket methods in python. setsockopt() is amongst them.
Just a little note - what I really needed is to bind to a specific IP, and just for the sake of completeness, the solution is to bind the socket after creation. Source in python:
import socket
s = socket.socket()
s.bind(("127.0.0.1", 0))
s.connect(("321.12.131.432", 80))
import socket
s = socket.socket()
s.bind((get_ip_address('eth0'), 0))
from Quora

Resources