How to send data from the same port after listening in c++? - c++

When I do the following steps to receive a message and send a reply, it fails.
I am using TCP. I need the program to send data from the same port it received from.
bind()
listen()
accept()
recv()
connect()//it fails to connect here using the same socket.<br>
send()

It seems you have a problem in understanding the way tcp works. There is a server and a client. The server waits for connections, and the client makes connections. Once a connection is established, the server and the client can communicate bi-directional (i.e. both can send and recive messages). Of course, their role might change, but this is the way it works. So, the server does:
bind()
listen()
accept()
recv()
send()
It is stuck at accept() until a client performs connect() on the port that the server is listening to.
As my explanation is pretty brief, I suggest you read this tutorial about linux sockets.

Related

Winsock: Listen and recv (differences)

I found this defeinitons of funcion listen and recv in winsock library (TCP/IP stream communication).
The listen function places a socket in a state in which it is listening for an incoming connection.
The recv function receives data from a connected socket or a bound connectionless socket.
Does it mean that if I want to receive data from particular socket I should firstly use listen and then recv? I'm not sure if I understand this correctly.
The functions listen and recv have quite different functionalities and uses.
The listen function is designed to allow a server awaiting the connection of one or more clients to listen on a port for if anyone connects.
The recv function is used on an already established socket to receive data which has been sent from the machine at the other end of that socket.
As it has been mentioned in comments, I shall also mention connect. Connect is the counterpart of listen. It talks to the port which a listening machine is listening on and establishes a socket with that machine.
what the BSD socket and winsock libraries don't really make clear is that from a programmers perspective there are two quite different kinds of socket, a listening socket and an established one.
A server will first need to create a listen socket with which it waits for clients, this socket is not used for actually sending any data, it only exists in order to aid the creation of an established socket. However the listening socket does not become the established socket, when a client connects, the listen socket actually creates a second socket for the data transfer.
The established socket is the kind we recognise and use for most things. It is a socket with machines at both ends, listening and sending to perform data transfer.

winsock udp connect missing or dropped packets

I am in the process of adding client/server UDP support to thekogans stream library and have run into a problem on Windows. Here is what I am doing;
server udp socket is bound to 0.0.0.0:8854.
server udp socket has IP_PKTINFO = true.
server udp socket has SO_REUSEADDR = true.
server udp socket starts an overlapped WSARecvMsg operation.
client binds to 0.0.0.0:0 and connects to 127.0.0.1:8854.
client sends a message using WSASend.
server socket receives the message and creates a new UDP socket with the following attributes:
SO_REUSEADDR = true
bind to address returned by IP_PKTINFO (127.0.0.1:8854).
connect to whatever address was returned by WSARecvMsg.
client and the new server UDP socket exchange a bunch of messages (using WSASend and WSARecv).
Here is the behavior I am seeing:
the first connection between client and server works flawlessly.
I then have the client exit and restart.
all other packets from the client are dropped.
if I set a timeout on the new server UDP socket (127.0.0.1:8854) and it times out and is closed, then the client can connect again. In other words, the scheme seems to work but only one client at a time. If the server has a concrete (not wildcard) socket created for the same port, no other client can send it messages.
Some more information that may be helpful: The server is async and uses IOCP. This code (using epoll and kqueue) works perfectly on Linux and OS X. I feel like I am missing some flag somewhere that winsock needs set but I can't seem to find it. I have tried googling various search terms but have hit a wall.
Any and all help would be greatly appreciated. thank you.

sending and receiving udp packets on same port

i need my client app to be able to sendto() and recvfrom() through the same port using UDP.
I have discovered i can only bind one socket to the port and it's better to do it when using recvfrom(), otherwise things mess up.
I want to be able to still send UDP packets through that port but binding it to a different socket is a problem as i mentioned above.
What can i do ?
thanks.
This should work fine. One socket bound to a port where you use recvfrom() and sendto() on the same socket. See this example from MSDN that shows recvfrom() in isolation - right around the recvfrom() you should be able to sendto() using that same socket.

Resetting socket connection

My application connects as a client across an ethernet to a server process.
As the server is well known and will not change, UDP and TCP are both setup using
socket();
setsockopt(SO_REUSEADDR);
bind();
connect();
The connection protocol includes heartbeats sent both ways.
When I detect an error with the connection e.g. hearbeat timeout, I need to reset the connection.
Is it sufficient just to connect() to the NULL address and then re-connect() after a short pause, or should I close the socket and then reinitialise from scratch?
thanks
After a socket error you have to discard the one in hand and restart the setup with a new socket.
Winsock documentation, for example:
When a connection between sockets is
broken, the sockets should be
discarded and recreated. When a
problem develops on a connected
socket, the application must discard
and recreate the needed sockets in
order to return to a stable point.
You have to close(2) the socket and re-do everything again. Why do you bind(2) on the client?

client socket sends data but server socket does not receive them. c++ buffered stream?

I am working on a project where a partner provides a service as socket server. And I write client sockets to communicate with it. The communication is two way: I send a request to server and then receive a response from server.
The problem is that I send the data to the server but apparently the server cannot receive the data.
From my side I just use very simple implementation just like the example from http://www.linuxhowtos.org/C_C++/socket.htm
#include <sys/socket.h>
socket_connect();
construct_request_data();
send(socket, request_data, request_length, 0/*flag*/); // I set flag as 0
// now the server should receive my request and send response to me
recv(socket, response_data, response_length, 0);
socket_close();
And it seems that the server socket is implemented with a "binding" to std::iostream and it is buffered stream. (i.e. the socket send/recv is done in iostream::write/read.)
server_socket_io >> receive_data;
server_socket_io << response_data;
Btw, I got a test client from my partner and it is wrapped in a iostream as well. The test socket client can communicate with the server without problem, but it must do iostream::flush() after every socket send.
But I want to just keep it simple not to wrap my socket client in iostream.
I just wonder whether the buffered iostream results in the problem: the data is not processed since the data the client socket sent is just in very small amount and still buffered.
Or could it be my problem? how can I know if I really send out the data? does my client socket also buffer the data?
I have tried some "bad" workaround with TCP_NODELAY but it didn't help!
How can I solve the problem? from client side? or server side?
Should I close the socket after sending request and before receiving response, so that the data will be "flushed" and processed?
or should I wrap my socket in iostream and do flush?
or the server socket should use a "unbuffered" stream?
thanks for any suggestion and advice!
Further to Jay's answer, you can try any network packet sniffer and check whether your packets are getting to the server or not. Have a look at wireshark or tcpdump.
Let's use "divide and conquer" to solve the problem.
First, does the server work?
From your code look up the port number that your server is listening on.
Start your server program.
Run the following command line program to see if the server is really listening:
netstat -an -p tcp
It will produce a list of connections. You should see a connection on your selected port when the server is running. Stop the server and run the command again to ensure the port is no longer in use.
Once you've verified the server is listening try to connect to it using the following command:
telnet your-server-address-here your-port-number-here
telnet will print what your server sends to you on the screen and send what you type back to the sever.
This should give you some good clues.
I had a similar issue once before. My problem was that I never 'accepted' a connection (TCP) on the server inorder to create the stream between server/client. After I accepted the connection on the server side, everything worked as designed.
You should check the firewall settings for both systems. They may not be passing along your data.