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?
Related
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.
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.
Currently have a winsock application that connects to a server. It can send and receive packets, but after a few minutes(around 2, if you wanted me to guess) of not sending anything, it disconnects and I have restart it, which is pretty annoying. Thanks in advance.
You can try setting KEEPALIVE to true. You set this using the socket options. You have to set it on both the client socket and the server's listening socket.
Have a look at:
http://linux.die.net/man/2/setsockopt
And
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740476(v=vs.85).aspx
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.
I have a Winsock based server application which uses Windows Winsock I/O Completion Ports.
As such, each connection accepted is associated with the listening socket to start receiving notifications (read, write, close etc').
The listening socket has a backlog of 100 pending connections.
All is good.
At some point I want to stop accepting new connections yet keep communication with already connected existing connected sockets.
I figured I could do one of:
Stop calling WSAAccept().
Set the backlog to zero, effectively disallowing any connection to pend.
Call shutdown() & closesocket() on the listening socket.
Now, option #1 gives the expected results; My application doesn't process new connections, BUT it does accept up to the backlog's amount (100). Connections are practically made - I don't want it!
Option #2; Can I do that? How? Couldn't find on MSDN nor google. The documentation of listen() at MSDN says;
If the listen function is called on an
already listening socket, it will
return success without changing the
value for the backlog parameter.
Setting the backlog parameter to 0 in
a subsequent call to listen on a
listening socket is not considered a
proper reset, especially if there are
connections on the socket.
Not good for me.
If I could do so in a safe way I would combine it with option #1, effectively really stopping establishing any new connections on the machine (through the listening port!).
Option #3 actually works; After closing the listening socket I can still communicate with existing connections, and the backlog is gone (well, closed the listening socket!).
My concern is that this approach might have some side-effects. Can anyone confirm?
You can simply close the listening socket. The accepted connections have their own sockets and they will not be affected by closing the listening socket.
For example, in the Microsoft documentation there is a sample server application where basic socket usage is demonstrated. There the listening socket is closed before communication over the accepted socket is done (before the do-while-loop).