How to verify ACK packet with write function in TCP client? - c

I'm trying to write a TCP client with write function following this: guide.
I shut down my network and try to send a PING package with 2 bytes of data.
Since it's a TCP client, I expect some kind of error returned because there is no network at all and the server won't be able to receive the message, hence no ACK packet will be returned. However, write function returns 2 bytes were written, seem like it doesn't verify ACK packet from server side at all.
How could I check for ACK to make sure whether my message is sent successfully and server receive it?

If you run both client and server on the same machine they'll communicate through the loopback interface, so unplugging or deactivating the outbound network interface will not change anything. Your server and client communicate happily with each other. If there truly isn't any connection between server and client the connect() should've failed with errno set to ENETUNREACH or ECONNREFUSED if the server refuses the connection. So what you probably want is to run the client on your machine and the server either another computer or in a VM with a bridged network. Note that write() successfully returning only means that the bytes are buffered to be send. It may even return fewer bytes than your message contains, indicating the buffer is currently full and you need to try sending the remaining bytes later.
The best way to analyze protocol implementations is using a tool like wireshark to see what packages are actually sent over the wire (or through the loopback interface).

Related

How to retrieve server program ip by client program by only knowing the port number in a LAN?

I am a rookie trying to learn winsock programming in c. Please tell me if the following is possible.
And sorry if the question is silly.But I really want to know the answer.
I am trying a client program which can search the network for its relative server with only the specified port number . The client must find the IP which provides the service in that specified port and then retrieve that ip back to client program.All this in the same system or in a LAN.
one of my friends said that I must use the Multicast DNS or UDP in the first part of the client to get the ip. After getting the ip then I could create the tcp connection with the server.
Is it really possible to send the clients ip to server through udp and initiate a tcp connection from the server to the client.
I have a basic idea what multicast DNS is.But I am not versed enough to use it in a live program.
Can anyone tell what winsock2 commands I must use for these operations?????
And sorry if I am being silly to your eyes.
one of my friends said that I must use the Multicast DNS or UDP in the first part of the client to get the ip. After getting the ip then I could create the tcp connection with the server.
What your friend is referring to is typically implemented using a UDP subnet broadcast. The client sends a UDP message to the LAN subnet's broadcast IP address on a specific port. IF the server is on the same subnet as the client, and IF it is listening on that UDP port, it will receive the message and can send a response back to the client IP/port that sent the message. When the client receives that response, it will know the server's IP and can then connect to the server's TCP port.
Another option is IF the server uses Multicast to broadcast its TCP IP/port periodically. A client could join the multicast group, receive the broadcasted IP/port, and then connect to it.
Is it really possible to send the clients ip to server through udp
Yes, by sending a UDP broadcast message to the entire subnet on a given port. All machines listening on that UDP port will receive the same message, and can choose to either ignore it or respond to it.
and initiate a tcp connection from the server to the client.
The client would still have to initiate the connection to the server. The broadcast simply allows the client to discover the server's IP without having to hunt for it.
Can anyone tell what winsock2 commands I must use for these operations?
IF the server can respond to a UDP broadcast, the client can use sendto() or WSASendTo() to send the broadcast, and then use recvfrom() or WSARecvFrom() to receive the response. Use GetAdaptersInfo() or GetAdaptersAddresses() to discover the LAN's subnet broadcast IP address. The broadcast port must be known ahead of time.
IF the server broadcasts its IP using multicast, the client can use setsockopt(IP_ADD_MEMBERSHIP) or setsockopt(MCAST_JOIN_GROUP) to join the multicast group, and then use recvfrom() or WSARecvFrom() to receive the broadcasts.
Of course, in either approach, the actual format of the broadcast message(s) must be known ahead of time.
And IF the server does not support either approach, you will have to resort to a manual brute-force scan of the subnet. Given the client's assigned IP address and subnet mask (again, obtainable from GetAdaptersInfo() or GetAdaptersAddresses()), you can easily calculate the first and last IP addresses of the subnet, and then connect to the TCP port on every IP address of the subnet until you find the server.
Yes, It is possible...
See what you need to do is broadcast initial request(What should be the response , must be known to you.. Kinda like handshaking) in your network on that specific port. Now whichever device will respond that way you will know that..
Make server in such a way that for initial request it would reply with it's IP and details...
If you are in same LAN then only it is possible.

UDP server, how can do that each thread will receive the right client's packet and not others?

Well, i have to do a udp server in C on linux.
This is my issue, for example:
I have that each thread will manage a client. But recvfrom will accept packets from any source, so, how can do that each thread will receive the right client's packet and not others?
I hope I explained my issue well.
Thank you!
(I mean that my server will make a new thread for each client that want to be served. So with TCP i can use accept to have a "dedicated" socket for each thread-client connection, but with UDP i can't do the same.)
You can't have multiple threads reading from the same socket at the same time.
What you should do instead is either:
have a dedicated thread that receives all inbound packets, looks at the source IP/Port, and routes the data to the appropriate processing thread as needed.
give each processing thread its own socket that is bind()'ed to the same local IP/Port and connect()'ed to the particular source IP/Port it is interested in, then each thread can call recvfrom() independently and it will only return packets that match the source that the thread is expecting.
UDP is a message based connection-less protocol. Here, there is no definite connection / setup done between the client and server prior sending the data. It does not maintain any states for communication at either client or server. UDP uses datagram socket(SOCK_DGRAM) . This ensures each packet sent or received in any order but with preserved message boundaries.
TCP is a stream based connection oriented protocol. Here , a definite logical connection is setup between the client and server prior to the exchange of data. TCP states are maintained for communication. TCP uses stream socket(SOCK_STREAM). This provides a connection-oriented, sequenced flow of data with mechanisms for creating/releasing connection and for detecting errors.
In header of TCP and UDP , only port number will be present. It is the responsibility of the IP header to add the necessary destination IP address for routing. However the source ip address shall be obtained from the source host.
In both TCP server and UDP server, once the socket is created using the particular socket type, it is bound to the port using bind system call. This is done so that the client can address to this port of the server. The procedure of binding is not necessary in either the TCP client or UDP client, because it does not matter in whatever port the client communicates. Till this point, it is same for both TCP server and UDP server.
In the case of TCP server, the listen system call will be invoked to listen for connections on the particular socket. The listen indicates the limit on the number of connections that can be queued up and that the server process is ready to accept any new incoming connections on the socket.
The server calls the accept system call which is a blocking call that waits for incoming connections.
Once a new connection comes, a new socket descriptor is created and the connection gets established between the server and client. However, as server, it has to keep listening for new connections.
This is where the multiprocessing begins to get into picture. Since connections can be triggered by any client at any time by using connect system call, we need to have the accept call(blocking call)for the new connections. Further, to have these new connections processed in parallel, one option is to fork and create a child process which will in-turn take care of further processing of the new connections while the parent process waits for new connections on accept call. This is how individual client connections are identified and processed/handled in the server. In simple terms, in concurrent server architecture, there will be one listening socket and multiple connected socket end points at the server at any time.
Note : The connect system call from client triggers the TCP SYN from client for starting the 3 way handshake procedure. At this point of time, the client socket state is SYN_SENT and once the SYN reaches the server, the server socket state is SYN_RCVD. Then the server responds with SYN_ACK to client for which client will respond with ACK and this establishes the connection between client and server.
In the case of UDP server, there is no need for this initial connection establishment as it is a message based connection-less protocol using datagram socket(SOCK_DGRAM). So, UDP client will not need the connect call for connection establishment which turn strips off the need for listen and accept calls in the UDP server. So, the UDP client server architecture shall be a iterative architecture where every client request/response shall be sequentially processed as iterative server architecture are applicable for services like UDP(light-weight) that consume less processing time. Also note that since the time consumed for processing is less, iterative servers will be state less.
In the case of requirement of multiple threads listening on same socket, you can also go for select or epoll system call based software architecture, where every thread will be waiting on select call but in this scenario, it may not be of great help. An alternate design that can meet your requirement can be a combination of separate thread for receive,parse & dispatch that will direct multiple processing threads.
That's why you have a port number.
If your server is listening on say, port 8080, no other process will be allowed to bind a socket to that port.
All clients that want to connect to this server will need send their data to port 8080 on the server's IP.
The UDP datagram has a source IP and port - you know where it came from, so you can route it appropriately.
You may well need a dedicated thread to send to the port, maintain state and later match up replies with requests so that the originating thread can be signaled that it's own reply is available. This could be done by providing a callback in the request struct that the rx thread signals when the matching reply arrives. The callback could signal a synchro object that the originating thread is waiting on.

Is connect() necessary if I want only to receive data in C/TCP?

if I want ONLY to receive data from a client, and not send data out, is it necessary have a connect() in the code of my server?
Or is it sufficient to have the following?
socket();
bind();
listen();
accept();
This describes the basic principle of server-client interaction. As you can see, the client must connect to the server before any interaction.
Once you've built a socket descriptor with the socket() call, you can connect that socket to a remote server using the well-named connect() system call.
Also the sequence you mentioned is in the server. If you want to only receive data from server, just do the read in client and write in server. But connect is neccessary.
You need to use socket and connect for the client.
The TCP protocol does send data to the server and recieves data back from the server (even if you are not transferring data) in the form of ACKs
Please read up on the TCP/IP protocol.
if I want ONLY to receive data from a client, and not send data out, is it necessary have a connect() in the code of my server?
It is never necessary to have connect() in the code of a server.
Clients call connect(). Servers call accept(). By definition.

MQTT recv from a publish and mqtt ping C

i've got this problem, in a test program, where i'm developing a client for MQTT, i'm subscribed on a topic, after that, i wait for "publish" message from the server to my client.
After a good recv (of a publish message) or after a recv timeout i send a mqtt PINGREQ to the server.
After a A PINGREQ i'm going to wait a PINGRESP, then i call a recv as in the case I were waiting for a PUBLISH message.
If the flow is this:
Client -> PINGREQ
Server -> PUBLISH
Server -> PINGRESP
Than the server publish message were lost. How to solve this? I'm using MQTT at QOS 0, it make sense solve this problem on this level of QOS or instead is smart to check this case at QOS1?
I think you've got things a bit confused. PINGREQ/PINGRESP are used when there isn't any other network traffic passing between the client and server, in order to let both the client and server know if the connection drops.
Your client should keep track of the when the last outgoing or incoming communication with the server was, and send a PINGREQ if it is going to exceed the keepalive timer it set with its CONNECT command. The server will disconnect the client at 1.5*keepalive if no communication is received. The client should assume the server has been disconnected if it does not receive a PINGRESP in response to its PINGREQ within keepalive of sending the PINGREQ.
The QoS level isn't that important, you have to ensure the keepalive timeout is maintained regardless.
It also occurs to me that it sounds like you're using blocking network calls - it might be best to move to non-blocking if you can to get more flexibility.

Multiple TCP connections in C

Can a process open/maintain 2 TCP connections in parallel? [for sending and receiving].
I tried the following scenario :
1) Client connects to server on one port, say 13101.
2) Once it sends, it will wait on another port 13102 to get the ACK.
3) Here Server can handle multiple connections [using select() on same port number].
Now, I am facing 2 problems:
1) Server on receiving data from Client1, it is processing data and for sending the ACK back [to client1], I am preparing a new TCP connection [with port 13102] and trying to send data. It fails with "Connection Refused".
2) In order to verify the above problem, I wrote another client2 program that just sends data to port 13102 [to client1, when it is in listening mode]. Still client2 is getting "Connection refused" error.
Yes, you can open lots of sockets! However, you shouldn't need separate sockets for sending and receiving, a TCP socket is bi-directional once it's opened.
As for your error, if you're using two machines, there could be a firewall preventing the server from connecting to your client. You might try using telnet to try to connect to the same port.
The error is probably because the client is not listening for an incoming connection. As stated above you can use a single socket for both send and receive.

Resources