FTP implementation: close data socket every time - c

I'm implementing in c a sort of FTP protocol.
I' ve a server running.
I start the client, connect to the server, and then send a GET file.txt request.
The client parse the command, see it's a GET command and starts a server socket.
The server recieves the command, and starts the data connection with the client and start sending file.txt on this connection.
When the server sent the file, it closes the client socket (Data).
When i want to GET another file, the port is already in use. How can i prevent this? Should i keep the data-connection open for all the command-connection session? In this case, how can my client know when the file is over?
Thanks

When a socket is closed, it enters the TIME WAIT state (see here for the possible TCP states) and no other socket can be bound to the same address/port pair until the socket leaves TIME WAIT and is in the CLOSED state.
You can go around this by setting the SO_REUSEADDR socket option, that will allow two sockets to be bound to the same address if one of the sockets is in the TIME WAIT state.

you need to open socket for transfer each time as the server will close it when transfer finish.
you will know that the file is downloaded/uploaded by reading response from FTP Server for status code (226 or 250) - check List of FTP server return codes:
https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes

In my project, I use apache-commons-net,
just keep the command connection alive with heartbeat command,
and enter local passive mode every time to do file tranfer.
The principle is same for your situation, I suggest send
EPSV
command before GETTING a file.txt.
refer: https://commons.apache.org/proper/commons-net/

Related

Closing websocket connections using libcurl when server sends close signal

I'm not an advanced user, so please cope with me.
I'm trying to implement a WebSocket client using libcurl, and I'm good until the last step of a connection - termination.
The general logic is as follows:
Client connects and sends an upgrade request.
Websocket server accepts/upgrades and starts sending gibberish.
Client adds up all the gibberish sizes.
Server sends a closing signal after 10 secs.
So far so good. I'm not processing the payloads of incoming messages, and I don't want to. I have very limited resources and I don't want to experience any performance loss in order to check each payload and search for a close signal.
I'm using libcurl's easy interface and receive data with curl_easy_perform(). Is there any way to detect a close signal, or close the websocket connection after 10 secs?
Close signals are part of the WebSocket protocol at the framing layer (see RFC 6455 Sections 1.4, 5, and 5.5.1).
AFAIK, libcurl doesn't natively support WebSockets, just HTTP (which a WebSocket uses for its opening handshake, so you can fake it with libcurl). So, if libcurl doesn't process the WebSocket frames for you, you would have to process them yourself, even if you ignore their payloads.
Otherwise, just set a 10-second timer for yourself and close the underlying TCP connection directly, which you can get from libcurl using curl_easy_getinfo(CURLINFO_ACTIVESOCKET).
But, if the server is sending you a close signal, you SHOULD send one back, per Section 5.5.1, which means parsing the frames properly:
If an endpoint receives a Close frame and did not previously send a Close frame, the endpoint MUST send a Close frame in response. (When sending a Close frame in response, the endpoint typically echos the status code it received.) It SHOULD do so as soon as practical. An endpoint MAY delay sending a Close frame until its current message is sent (for instance, if the majority of a fragmented message is already sent, an endpoint MAY send the remaining fragments before sending a Close frame). However, there is no guarantee that the endpoint that has already sent a Close frame will continue to process data.
After both sending and receiving a Close message, an endpoint considers the WebSocket connection closed and MUST close the underlying TCP connection. The server MUST close the underlying TCP connection immediately; the client SHOULD wait for the server to close the connection but MAY close the connection at any time after sending and receiving a Close message, e.g., if it has not received a TCP Close from the server in a reasonable time period.
If a client and server both send a Close message at the same time, both endpoints will have sent and received a Close message and should consider the WebSocket connection closed and close the underlying TCP connection.

Use of fork command in C in a chat application

I have a problem in this question, please anyone can guide me
Communication between client and server in C ubantu:
Client will send message and address of another client to server and server will forward that message to that client. Other client will reply to server in a same format and server will forward that message to specified client.
I have to use fork command in this Question.
How I will send address to server and message together?
I don't think you should use fork in this case. You can keep an array containing your client's sockets with a unique ID, which can be the address, and forward the message you receive from a client to the one with the ID specified in the original message. The select() system call can be useful when monitoring an array of file descriptors.

closing the client after the file descriptor in server is closed using close(fd) in server

I have a scenario to close the connection in server if the client is inactive for say about 120 sec. It is intended such that I could reuse the fd after certain time inactivity.so I wrote a code to close the file descripter using
if ((int)time(NULL) - (int)value_data->timeout > 120)
{
zlog_warn(_c,"timeout of 120s for device = %s",key);
close(value_data->fd);
g_hash_table_iter_remove (&iter);
(*_collector_free_tcp_cache_cb)(value_data->device_ip, value_data->fd);
AFREE(value_data->device_ip);
AFREE(value_data);
}
using close(fd), in server side the connection fd is closed. The problem I am facing is after next time the client is connected, the server is crashed. The client is not able to send the data. While looking in the tcp client side, it gives information that the Tcp is in
TCP 192.168.2.138:50296->192.168.2.161:shell (CLOSE_WAIT)
how can i send the data starting next client again? is there certain time I need to wait such that the same fd can be reused to send the data.?

C: Using select() to write to new client

I'm creating a chat server/client using C and I'm using select() to monitor my sockets.
The program is separated into 3 parts, the server, the viewing client. and the submitting client. The submitting client connects a socket to the server and when there is text to be read from the client, select triggers that it needs to be read. If it's a new client connection, select will also trigger so that I can accept the connection and assign a socket to the client.
My issue is with the viewing client which is supposed to trigger select when it is writable. However, when there is a new connection, select doesn't do anything.This source claims that select will only be triggered on write-fd if they have already been connected. However, how can I connect a new writing client?
server:
if (select(128, &read_fds, &write_fds, NULL, NULL) == -1){
...
}
if (FD_ISSET(viewing_socket, &write_fds)){
printf("%d is a new observer connection\n", viewing_socket);
new_observer_connection();
}
if (FD_ISSET(submitting_socket, &read_fds)){
printf("%d is a new participant connection\n", submitting_socket);
new_participant_connection();
}
So when a new submitting client connect, it accepts the connection and adds that new socket to &read_fds to monitor for reads. However, new viewing client connections don't seem to trigger a thing.
Seconds after posting this I found the solution. The listening sockets both need to be read from when there is a new client. Only after accepting the connection does the new socket get watched for writing. The socket listening for new connections obviously needs to be read from not written to. Will keep this up for others...

How To Send A File In Winsock (http Way)

I mean, if i have a winsock in window environmentand i set it to listen on port 80 and ip of server.then i have a file abc.txt or abc.xml .i have to send file from client to http server through http link. how can we send it .I don't know how to send text files.
Please..I need this...so badly.
Thanks in advance!
Setting up a server basically requires the following steps:
Open socket with socket()
Bind socket to an address (usually INADDR_ANY) and a specific port with bind()
Listen to the socket with listen()
Accept a connection with accept(). This returns a new socket number (the client socket)
Now you can receive data from the client socket with recv() and send data with send().
To send a file to the client, just read from the file for example line by line and then send it to the socket with send().
Of course you need to communicate the file name and size before you start sending. (Or use EOF character at the end of file).
For more information, see:
msdn: Getting Started with Winsock

Resources