I am currently starting to learn to program sockets with the C programming language. I was wondering in the situation of a server that receives multiple messages, let's say I want to transfer a file from the client to the server. My question in this scenario is, do I have to call multiple times the accept function before calling each time the recv function? Or can I simply accept once the connection from the client side once and call multiple times recv?
Assuming that you are using TCP connections ("socket programming" covers a wide variety of topics, but TCP is the most common) accept completes the connection via sockets between your application and a counterparty and sets up a different socket that should be used to transfer data. The actual data transfer happens on this new socket. So only call accept once per connection.
See this page for a detailed description of what accept does.
Related
I am new to C Socket Programming. I know how to write for TCP and UDP as different programs.
But only one server should handle both the clients.
Can anyone tell me how to write a sever that handles both TCP and UDP clients?
You cannot listen to TCP and UDP clients using 1 server socket. You can however create 2 server sockets (one TCP-server and one UDP-server). Note that it would not even make sense to have 1 server for both: UDP is connectionless so the first question arises when you try to do accept on your server socket (since it is a hypothetical hybrid version, what should accept do?).
Anyway, I assume you want two servers in the same event loop (if you don't know what it is, it is enough for you to think of it as your main-function). Since C sockets are blocking by default, you cannot run two servers right out of the box.
You can use select (Google it). If you don't know what it is, I would recommend to try it in Python first. In Python it's fairly straight forward and it will give you some insight of the concept. Basically what you do is: create multiple server sockets than "switch" between those sockets, see what sockets have read events (be it new connections or messages) and then process those events.
I can recommend libuv. It is a C library that is originally built for Node.js. Prior to libuv, they used platform-dependent event loop implementations (libev). Libuv originated as an effort to create a multi-platform library for non-blocking IO (TCP, UDP, fs, etc.). However, even if you don't want to write multi-platform code, it comes with a great API to create server sockets and listen to multiple sockets in the same event loop.
I'm writing a server in C ++ for both Windows and Unix systems.
A key feature of this server is that it must be able to receive and send network packets at any time.
Specifically, the server must be able to send data to the client not only in response to their messages, but also be able to send packets to them asynch in push.
I'm having difficulty in implementing a solution that uses the select() function in the scenario described above.
The solution I have currently implemented does not convince me at all and I think it can be implemented with better patterns/solutions.
I currently have a dedicated thread (selector) that performs the select by listening on events in the reading for the server socket (to accept new connections) and for the sockets connected to the server.
This is the main select() loop:
if((sel_res_ = select(nfds_+1, &read_FDs_, NULL, &excep_FDs_, &sel_timeout)) > 0){
if(FD_ISSET(serv_socket, &read_FDs_)){
//we have to handle a newly connection.
...
if(sel_res_ > 1){
//in addition to the newly connection, there is also some other message incoming on client sockets.
...
}
}else{
//we have to handle incoming messages on client sockets
...
}
}
This solution works well for receiving the data and to respond to client requests in synchronous form.
However, the server must also be able to send asynchronous data, and send when necessary, packets in push.
To do this I currently use separate threads that perform directly the send() on the client sockets.
This solution does not convince me, and I would like to centralize the packets receiving and sending on the selector thread.
The main difficulty is that the select() by its nature is blocking and I have no control until a client does not send any packet or the timeout is triggered.
The solution to set a timeout very low does not convince me; I see it as an easy solution that is actually doing active wait, and not only, however, the worst case I would pay the price of the timeout before sending the push packet.
I thought a more 'elegant' solution; I think, will work well, but only for a Unix/Linux platform.
I thought to use an anonymous pipe and insert into the select() read_FDs_ the anonymous pipe read descriptor.
In this way, when a thread wants to send a data in push, it writes something on this pipe, interrupting the select() and returning control to the selector that can then predispose to send the data to the client, without significant loss of time.
I think that this solution, unfortunately, cannot be implemented on Windows because the select() function on that system works only with fds that are actually sockets.
So the question is: Is there some well known solution that can be used to address this kind of scenario (both Linux and Windows)?
You can create a self connected UDP socket, this works equally well on Windows and Linux.
Basically, you create a UDP socket, bind() it to INADDR_LOOPBACK and port 0, and connect() it to itself (with the address taken from getsockname()).
At this point, you can send yourself a single byte message (or something more specific) to wake yourself up.
I have two questions regarding using sockets for client server communication. Assume there is only 1 client in both the cases.
1) I know that we can send and receive data between client and server using a single socket. But in that case, what will happen when both the server and the client try to send the data at the same time?
2) Which of these is the best model?
i) Using single thread, single socket for sending and receiving
ii) Using 2 threads(one for sending and one for receiving), single socket
iii) Using 2 sockets and 2 threads, one for sending and one for receiving.
The connection is full-duplex, meaning that sends and receives can happen at the same time. So in answer to question one, both client and server will be able to send/read data from their socket simultaneously.
In terms of which "model" is best, it depends on your application and what you're trying to achieve. Incidentally, you don't need to multi-thread. You could:
Multi-process (fork)
Use non-blocking sockets (select/poll)
Use asynchronous notification (signals)
All of which have pros and cons.
For question number one, nothing special will happen. TCP is fully duplex, both sides of a connection can send simultaneously.
And as there is no problem with sending/receiving simultaneously, the first alternative in your second question is going to be the simplest.
In that scenario you dont need threads. The sockets themselves buffer the incoming data until you read it from the file-descriptor. More precisely there are multiple levels of buffers starting at the hardware. You will not miss data because you were writing at the same time, it just waits for you until you next read from the socket's file-descriptor.
There is no inherent need for multithreading if you want to poll at multiple sockets.
All you really have to do is use select().
To achieve this you define a FD_SET (File-Descriptor Set) to which you add all the sockets you want to poll. This set you hand to select() and it will return you all file descriptors with pending data.
man page for select, fd_set and a select tutorial
I am writing a C program where for every new request to be processed by server, I need to open a new TCP connection? That is every request from client needs to be handled by a separate TCP connection to a server listening on a particular port.
Can someone help me in code pointers?
How to maintain array of this socket identifiers (multiple sockets that needs to be opened)
How will I be able to read (Need to scroll through all open sockets and see if something interesting is to be read upon that socket)
Any code snippet will be highly useful?
You can use the select() function (assuming you are working with <sys/socket.h>), "gives you the power to monitor several sockets at the same time. It'll tell you which ones are ready for reading, which are ready for writing, and which sockets have raised exceptions" from http://beej.us/guide/bgnet/ (here you can download a pretty good book on network programming basics).
For a server example using select check http://beej.us/guide/bgnet/examples/selectserver.c
Hope it helps
If you need to save state with the socket, put it in a struct together with the data you need, and link the structures together as a list. For checking which sockets are ready see Maluchi's answer.
Okay I'm brand new to socket programming and my program is not behaving like I'd expect it to. In all the examples that I see of socket programming they use accept() and all the code after assumes that a connection has been made.
But my accept() is called as soon as I start the server. Is this supposed to happen? Or is the server supposed to wait for a connection before executing the rest of the program?
EDIT: Oops I forgot to mention it is a TCP connection.
I think this is what you're after.
http://www.sockets.com/winsock.htm#Accept
The main concept within winsocket programming is you're working with either blocking or non blocking sockets. Most of the time if you're using blocking sockets you can query the sockets recieve set to see if any call would result in your call to the routine being blocked..
For starting off with this UDP is easier considering its a datagram protocol. TCP on the other hand is a streaming protocol. So it's easier to think in regards to blocks of data that is sent and received.
For a server, you:
Create the socket - socket().
Bind it to an address.
You enter a loop in which you:
Listen for connection attempts
Accept and process them
It is not clear from your description whether you are doing all those steps.
There are multiple options for the 'process them' phase, depending on whether you plan to have a single-threaded single process handle one request before processing the next, or whether you plan to have a multi-threaded single process, with one thread accepting requests and creating other threads to do the processing (while the one thread waits for the next incoming connection), or whether you plan to have the process fork with the child processing the new request while the parent goes back to listening for the next request.
You are supposed to enter your acceptance loop after you have started listening for connections. Use select() to detect when a pending client connection is ready to be accepted, then call accept() to accept it.