I am implementing FTP Client in C++ using Windows Sockets. I have successfully connected to Server on Port 21, and transmitted the file in PASV mode using "STOR Sample.txt" command on the data port. The problem is that I am unable to tell the server about transfer completion (I want to send the signal to close data connection) so that i can receive the "226 Transfer OK" from the server on my control connection.
Further, I am not receiving anything from the server via recv(). I think that is because server is still listening on the data connection.
Have a look at this:
proper user of STOR command
You get back the port to connect to when you send PASV and then you tell the server where to store the data using STOR and the you connect to the port the PASV command returned and send the data - when you are done you close this second socket and continue sending commands with the original one.
Related
I have created simple TCP server which accepts connections and request and do some processing. I have referred following example and it is working fine. I send data to to connected client continuously and it is being printed on client side. Though after around period of 20-25 minutes, the client stops receiving any data. Also after such incident, the server shows running but now when I connect my client again to server, the server's connection accept handler doesnt get invoked. But I am able to telnet to the server's port and client is able to connect. Any idea what might be the problem?
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 writing a client-server application using sockets in C++.
The protocol for communications is essentially:
The client connects to the server.
The client "sends" an ASCII command to the server.
The server executes the command remotely, and gets the results, and sends the results back to the client.
the results can be multiple megabytes of data. Once all the results are sent to the client, I would like the server to signal the client that it's done.
Is the best way to closesocket(), or should it send a message that indicates to the client that there are no more results, and the client can decide whether to close the socket or not? The drawback with closing the socket is that the client will need to establish a new connection if it wants to execute another command, but the drawback of sending a message back from the server is that the client needs to scan every recv to determine if the results are done.
Which is the best practice?
I would take a slightly lateral approach:
Client sends command to server
Server send size of response and then the real response
Client can issue new command / close connection
In this way the client knows how much to read and can decide whether to close the connection or not.
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.
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.