I am now doing concurrent socket programming with C/C++. I just made the server to receive a request from client and sending the response packets to clients. I use one thread to receive requests from Clients. when the server got a new request, a new thread will be create in order to send some packets to clients. However, the recvfrom in my client side always return the winsock error 10054 while my server is sending packets out to that particular client.
This error message means the udp port is closed and you are receiving a packet on the closed port. For example in voip phone the client sends origport=12295 stating that please send the packet on this and will close the working port 32000
08:43:32.377 cip=172.x.23.225 sip=10.x.20.2 cport=32000 sport=32128 origport=12295
But if the server don't understand this and you still receive the packet on 32000 from server then client will show this error message
According to this forum thread, it is a harmless error and you can just ignore it in the client.
Related
I have been looking at a lot of Boost.Asio tutorials, especially this one:
TCP daytime server
After a server creates a tcp_connection with a client, it seems like the communication is only one-way between the server and that specific client. How can I make it so a server has the ability to relay client messages to all of the clients connected? Or even choose which clients to send messages to.
TCP create only connexion between the server and a specific client. You can use UDP connexion to broadcast message to several clients.
Like JTejedor says in comments, you can also create a TCP socket for each client.
Overview
In c++ (gcc-c++ 6.3.1) on Fedora 24 x86_64 using the standard sockets API, I am making a basic FTP client based on a select few components of RFC-959. I am running into the occasional problem that when receiving or sending data to a server, the data connection gets reset. I have no trouble closing the socket and continuing execution in the case of a data read, but my program trips up quite seriously when performing a write (such as with put/STOR).
There is a lot of code in this program so far, so I will include the most relevant parts in my answer and attempt to abstract the rest. If additional segments of code are needed, I will add them by request.
Detailed Process
Assume that the control connection is already functional and a user is authenticated.
I query passive mode to the server (PASV).
I receive passive response (227).
I open the data connection given the response's IP and port number.
I query a store request to the server (STOR)
I receive store approval (150)
I call send() for the first time, sending some of the data, but -1 is returned.
The errno value is verified equal to ECONNRESET
I attempt to close the socket
I read the control connection for the confirmation from server (226)
Observations
When attempting to close the connection in step 8 above, I have tried a few different things.
shutdown(fileDescriptor, [any flag])
returns -1, ENOTCONN/107, Transport endpoint is not connected.
close(fileDescriptor) returns 0 for success (occasionally I have seen ECONNRESET here too).
This behavior does not change when setting SO_LINGER to immediately close. In fact, the most interesting part is that after the server sends an Rst packet to me, my client never sends its own Rst or Fin until I terminate the program.
Enabling TCP_NODELAY to disable Nagle's algorithm doesn't change anything.
Packet Watch: Standard FTP Client
This is observing packets transferred on the standard FTP client that comes with most unix operating systems.
Packet Direction Purpose
ftp: PASV --> Client prompt for passive mode
ftp: 227 <-- Server approve passive mode
tcp: Syn --> Client initiate handshake for data connection
tcp: Syn+Ack <-- Server acknowledge handshake
tcp: Ack --> Client acknowledge acknowledgement
ftp: STOR --> Client prompt to store file
ftp: 150 <-- Server approve of store request
tcp: Rst+Ack <-- Server warns that connection is closed/reset
tcp: Fin+Ack --> Client closes connection
tcp: Ack --> Client acknowledges server
ftp: 226 <-- Server sends response that file upload done
Differences On My Client
If you observe the same transaction from my client, the Fin+Ack or Rst packets is never sent when close() or shutdown() is called.
After this data connection fails to close, the control connection refuses to send any more responses, which causes all future commands to hang up. But once I close the program, resets are sent on all open connections, and the connections close.
Does anyone know of any obvious troubles I might be running into when trying to terminate the data connection? Why doesn't shutdown() or close() actually close the socket, and how can I force it to not return until it succeeds in doing so?
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.
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'm working on a flash application that needs to communicate with my C++ server for things like account validation and state updates. I have a non-blocking TCP socket on the server listening on a specific port.
The process goes like this:
Socket listens on server machine
Flash connects using a flash.net.Socket
Server accepts socket connection
Flash sends a policy file request
Server sends policy file data
Flash accepts connection
Two problems occur from here on out. When I send bytes from flash the server doesn't recognize it at all but it doesn't block either. I just recv 0 bytes. When I send bytes from the server after sending the policy file I gives me a WSAECONNRESET error.
Resources for Flash communicating with C or C++ is very limited so any help is greatly appreciated.
When the flash client sends "<policy-file-request/>" the server should send the file and then close the connection.
The client will need to reconnect after it receives the policy.
Trust me on this.