I've been trying to use the socket() api in C but no luck so far.
I would like to send a request to a specific device (Address: 192.168.2.55 Port: 12850) which will then return data to the application. How do I do this in C. I'm on a Mac so "the Unix way" if that differs from Windows...
Thanks and merry christmas!
For socket programming introduction, see http://beej.us/guide/bgnet/
The steps involved in establishing a socket on the client side are as follows:
Create a socket with the socket() system call
Connect the socket to the address of the server using the connect() system call
Send and receive data. There are a number of ways to do this, but the simplest is to use the read() and write() system calls.
The steps involved in establishing a socket on the server side are as follows:
Create a socket with the socket() system call
Bind the socket to an address using the bind() system call. For a server socket on the Internet, an address consists of a port number on the host machine.
Listen for connections with the listen() system call
Accept a connection with the accept() system call. This call typically blocks until a client connects with the server.
Send and receive data
Check to see if you have followed these steps thusfar with the code you have written.
Related
I've been reading this tutorial to learn about socket programming. It seems that the listen() and accept() system calls both do the same thing, which is block and wait for a client to connect to the socket that was created with the socket() system call. Why do you need two separate steps for this? Why not just use one system call?
By the way, I have googled this question and found similar questions, but none of the answers were satisfactory. For example, one of them said that accept() creates the socket, which makes no sense, since I know that the socket is created by socket().
The listen() function basically sets a flag in the internal socket structure marking the socket as a passive listening socket, one that you can call accept on. It opens the bound port so the socket can then start receiving connections from clients.
The accept() function asks a listening socket to accept the next incoming connection and return a socket descriptor for that connection. So, in a sense, accept() does create a socket, just not the one you use to listen() for incoming connections on.
It is all part of the historic setup. listen prepares socket for the next accept call. Listen also allows one to setup the backlog - the number of connections which will be accepted by the system, and than put to wait until your program can really accept them. Everything which comes after the backlog is full well be rejected by the system right away. listen never blocks, while accept will block (unless the socket is in non-blocking mode) until the next connection comes along. Obviously, this does not have to be two separate functions - it is conceivable that accept() function could do everything listen does.
The above two answers clearly state the difference between accept and listen. To answer your other question - why we need two separate functions?
One use case is, for e.g. if you only want to test if a port is still available/and accessible, you can do so by just listening to the port and then closing it without accepting any connections.
For e.g. https://github.com/coolaj86/golang-test-port uses the listen call for testing a port's availability.
listen() uses a backlog parameter which specifies the maximum number of queued connections and should be at least 0. It's value increases as the server receives a lot of connection requests simultaneously.
accept() waits for incoming connections. When a client connects, it returns a new socket object representing the connection.
Another imperative thing to note is that accept() creates a new socket object which will be used to communicate with the client. It is different from the listening socket that server uses to accept new connections.
Maximum number of sockets allowed per each connection between an application and the TCP/IP sockets interface is 65535.
Bind function is used to assign a name (a sockaddr struct) to a socket descriptor. Why is it required for TCP server but not TCP client ? And why it is required for bot UDP Client and server?
I have also written correctly working code without using bind() in UDP Client .
I do not understand why bind() is not used universally i.e. in all cases above.
Binding is only a required, if there is no other way for the computer to know which program to send the packets to. For connection less programs this is only the receiving end.
Please have a look at socket connect() vs bind() this post.
There a much better job of explaining is done than I'm able to do. If you've got any questions after. Feel free to ask:)
Client on calling connect implicitly bind to a ephemeral, available port provided by the kernel. It need not specifically bind because it is the initiator of the connection. Server explicitly need to bind because it need to tell external world (the clients) how they can reach the server. Server listens on that port.Client knowing that published port initiates connection to it.
Now servers can send packets to client because on connection establishment the peer details (IP and Port) becomes known and are part of connection identifier.
And the above applied to both TCP and UDP. (UDP will not have connect)
I am writing on UDP server/client application.
I want my single server to handle 40 clients at a time. For this, I want to create 40 dedicated threads, each dedicated for one single client. Since there are 40 threads one for each client, I want to create 40 dedicated sockets as well.
But the problem that:
I don't know what will be the 40 IP addresses to which I shall bind() my sockets. (since as far as I now, I have to bind() to my Server\s IP address.) Normally I bind() to "INADDR_ANY" when there is only single socket.
But what should be the IP addresses at which I should bind() each of my 40 sockets?
Please help me. Any comment/ help is appreciated.
One common way to do this with UDP is:
Server bind() to a well known port.
Client sends the initial packet to that well known port
Server receive the first packet from a client on the well known port.
Server creates a new socket with a random port
Server replies to the client from this new socket.
Client receives the reply, notices it comes from another port than the well known
server port, and uses that port as the destination for further communication.
You'll use the getpeername() call to learn the remote address.
Keep in mind that UDP is connection-less, you'll need some way to signal the end or time out you sockets.
bind only needs the local address, not the remote address.
If you want one socket for each client, then you'll need to use different ports for each (using bind). That way, each client can send its traffic to a dedicated port, and you can have a thread for each socket/port.
It's probably a better idea to only have one socket (and one port) though, and have logic in your code to assign traffic to a thread based on the remote address (retrieved using recvfrom eg.).
The usual way is to bind a single socket and accept incoming connections. Each connection will be assigned a unique socket by accept.
As you are using UDP, I would simply use TCP as described above to let the clients know of their respective server UDP addresses.
Create a single listening socket in a dedicated listening thread.
When it receives a new packet, use the packet's remote addr/port, or put a unique clientID in the packet payload, to uniquely identify the client.
Create a new thread for that client if one does not already exist, pass the packet to that thread for further processing, and go back to listening.
If a given client thread does not receive any packets for awhile, it can terminate itself.
I have a small doubt in socket programming. i am able to send my data from client to server and my server processes the data. The o/p of the data processed, I want to send back to my client. So can we "write" the data back to the client using the same socket. I mean a server listens on a port before accepting connection and receiving data, so similarly, do i need to make my client listen to some other port (bind it some other socket) and make my server connect to that socket and transfer the data back. Any kind of example or explanation or references would be appreciated. Thanks a lot in advance.
Check out Beej's Network Programming Guide first of all.
The basic screenplay of a server/client connection goes like this:
Server listen()s on a fixed port, with a given socket.
Client connect()s to a the server port; client obtains a socket.
Server accept()s the connection, and accept() returns a new socket for the connection.
(Server continues listening on the original port with the original socket.)
For the specific connection with the client, the server write()s to the new socket it obtained when accept()ing the incoming connection. A busy server will have many, many sockets, but it will only ever need to bind() to one port. All connections come in to that one port, but the OS's networking protocol stack separates the data and makes it available at the connection-specific socket.
You don't need a new socket.
A socket is a duplex connection you can send data in both directions and you can even close the socket from one direction (don't want to write anymore) but still send data from the other direction.
Your socket is bi-directional, so there is no need to create another socket. Unless you are using some sort of middleware, such as Pub/Sub, there is no need to create another socket to enable bi-directional communication.
Technically it is right, the socket is duplex and you can send the data to the same socket you read from:
SOCKET s = socket()
... //Connect
int size = receive(s,...);
//make response
send(s, ...);
But in practice it depends on what are you going to do. It is possible to hang out socket if you have the following situation:
Process 1 sends very big data (<100K) over the socket by one send
operation
Process 2 receives data from 1 by portions and sends small packets to 1 (~20b). It is not a
confirmations, but some external events.
The situation goes into hangout, where the sending buffer of the 2 is full and it stops sending confirmations to 1.
2 and 1 are hanging in their send operations making a deadlock.
In this case I'd recommend using two sockets. One for read, one for write.
(Late answer, so mainly for anyone else who comes here looking for help)
I recently put up an example client/server application that closely follows Beej's Guide to Network Programming (which was also recommended by Kerrek SB in his answer). If you're looking for a simple working example of client/server communication, maybe this will help:
https://github.com/countvajhula/dummyclientserver
In particular, no, your client does not need to set up a separate listening socket to receive data from the server -- after the server has accepted the connection from the client, the server can simply send data back to the client on the same socket.
I am working on a code where I have need to find the sender's IP address,sender's port no and application layer packet sent by it.
I did it using Raw Sockets (SOCK_RAW), it runs fine and did the job for me but its too much clumsy.
Question: I can use SOCK_STREAM and get the application layer packet directly and that's really clean and simple method than using Raw socket but this way I won't be able to find the IP address and port number of the client. Is there any function to which I pass the socket descriptor and it tells me the IP address and port number of the other end. I read a few man pages but I could not find any.
I am using linux socket api in C language.
Thanks in advance. :)
When you call accept() to accept an incoming connection, *address is a structure that is filled in with the sender's IP address and port number.
the BSD socket implementation defines a function named getpeername() which allows to know the ip address and the port of the remote side of a tcp socket.
when you have any SOCK_STREAM connected socket, no matter which side first established the connection, you can call this function to get the informations you need. (this is far easier than a raw socket).