int udp_sock() {
//Create socket
sock = socket(AF_INET , SOCK_DGRAM , 0);
if (sock == -1) {
printf("Could not create socket\n");
}
puts("Socket created.......\n");
server1.sin_addr.s_addr = inet_addr("172.210.110.10");
server1.sin_family = AF_INET;
server1.sin_port = htons(PORT);
//Connect to remote server
con= connect(sock , (struct sockaddr *)&server1 , sizeof(server1));
if(con<0) {
perror("connect failed. Error\n");
return con;
}
puts("Connected\n");
return 0;
}
The packet is reaching server mentioned, but the error "destination port unreachable" comes up in Wireshark.
How to assign a UDP port on my client to receive data on a particular port?
How to assign two different ports - 1024 and 1025 to receive data?
Any suggestions will be helpful.
There needs to be a server waiting on the other end. A simple way for testing is to use netcat.
nc -lu 8053
Alternatively set up a utility that is designed for udp testing, such as echo server. This is normally built into an inetd or xinetd server
If you want to intercept incoming udp packets you will need to use bind() select()/poll()/epoll() and recvfrom()
Related
I have a server that listens for incoming connections and processes the data from a client. Then, on the same server, I want to open another TCP sockets that send the data to another server without using the set socket() option.
this a code example:
int main()
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
char server_message[50] = "Message recivied";
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(port);
int status_connect= connect(sockfd, (struct sockaddr *)
&serv_addr, sizeof(serv_addr));
if (status_connect < 0) {
printf("Error connecting to the socket \n");
exit(1);
}
listen(sockfd, 10);
int client_socket;
client_socket = accept(sockfd, NULL, NULL);
send(client_socket, server_message, sizeof(server_message), 0);
do {
char clinet_message[256];
recv(net_socket, &clinet_message, sizeof(server_resp), 0 );
sending_client_message(&clinet_message);
}while(1);
return 0;
}
I have a server that listens for incoming connections and processes
the data from a client. Then, on the same server, I want to open
another TCP sockets that send the data to another server without using
the set socket() option.
There is no specific limit on the number of unconnected, connected, and listening sockets that a system or an individual process may have open at any given time. It is routine for a system to have many, and not uncommon for individual processes to have more than one.
But you need to understand that each socket is represented by a specific file descriptor number (or even by more than one). The same file descriptor cannot refer to two different sockets at the same time. Furthermore, the same socket cannot be both connected and listening.
The socket() function is used to create a socket. From there, for a TCP socket, your options are to either
connect() it to a peer, OR
use it to listen() for and accept() connections from peers.
You cannot use the same socket for both. Instead, create separate sockets via socket() for listening and for initiating connections. Create multiple of each if you want to listen on multiple ports or connect to multiple peers.
No, you can not use a single socket for multiple connections. Not in Linux at least but it should not be possible in other OS'es as well. A file descriptor given out by socket() can not be associated with more than one connection. If you try to connect() to an already connected socket you just get EISCONN error. You need to either disconnect from the first server before connecting to another one or to get a socket() fd for every one of the TCP connections you want to have running simultaneously.
I'm working with TCP servers. Let's say I have a server running with a specific port, but then I want to connect a client to it, I would simply go through the typical procedure of socket, bind, listen, accept for the server and then socket, connect for the client. So let's say our server port is 4000, and our client port 4001. Now, I want to create a new client that will connect to my client on port 4001, but to my limited understanding, I cannot do this as a client. Port 4001 would have to pertain to a server and not a client (i.e. it would have to be listening). The issue arises because I don't think you can use the same port for both the server and client.
I've decided to attempt this through the sample code I've provided below. I call the program on the command line as follows:
If this is the first call of the server, then I simply call the program without any arguments and it will automatically run on port 3000. i.e. ./serverprogram
If I would like to connect a client on port 3001 to our server on port 3000. Then I would call the command line with two arguments, the first being 3001 and the second being 3000. i.e. ./serverprogram 3001 3000
#define PORT 3000
int main (int argc, char * argv[]){
int sfd = socket(AF_INET, SOCK_STREAM, 0);
int my_port = (argc == 3) ? atoi(argv[1]) : PORT;
if (argc > 2){
struct sockaddr_in c_addr;
c_addr.sin_family = AF_INET;
memset(&c_addr.sin_zero, 0, 8);
c_addr.sin_port = htons(atoi(argv[2]));
struct addrinfo *result = NULL;
getaddrinfo("AcaciaLinux", NULL, NULL, &result);
struct sockaddr_in *x = (struct sockaddr_in*) result->ai_addr;
c_addr.sin_addr = x->sin_addr;
freeaddrinfo(result);
if(connect(sfd, (struct sockaddr *) &c_addr, sizeof(struct sockaddr_in)) == -1){
perror("connect");
exit(1);
}
printf("We have connected to a server.");
}
if (sfd == -1){
perror("socket");
exit(1);
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(my_port);
saddr.sin_addr.s_addr = INADDR_ANY;
memset(&(saddr.sin_zero), 0, 8);
if(bind(sfd, (struct sockaddr*) &saddr, sizeof(struct sockaddr_in)) == -1){
perror("bind");
close(sfd);
exit(1);
}
if (listen(sfd, 5) < 0){
perror("listen");
exit(1);
}
struct sockaddr_in caddr;
saddr.sin_family = AF_INET;
int cfd;
unsigned int c_len = sizeof(struct sockaddr_in);
if ((cfd = accept(sfd, (struct sockaddr*) &caddr, &c_len)) == -1){
perror("accept");
exit(1);
}
printf("Alas, we have finally connected to a client.");
return 0;
}
Upon running the second instance of the program I receive the error "bind: Invalid argument". I am assuming that this is due to the fact that the port is already in use. Is there any way to bypass this, or is there any way to connect a server to a client, and allow the client to also act as a server using the same port
You cannot open a socket which can do the both listen and connect.
A TCP connection is identified by its two endpoints. Each of those, in turn, is identified by an (IP address, port) pair. Therefore, you cannot simultaneously have two distinct connections between the same two IP addresses with the same ports on each end -- if all of those properties are the same, then they are the same connection.
From the perspective of system interfaces, you cannot create that situation because the system will not allow you to bind an address / port pair that is already in use to any socket (a stronger constraint than is strictly required). This means that one machine cannot use the same port simultaneously for both a client socket and a server socket, even for different remote endpoints.
You can, however, have any number of simultaneous TCP connections that each differ from all the others in at least one of those parameters. In particular, you can have any number of connections between the same two machines, with the same port on one side, and different ports on the other. This is extremely common, in fact, as web browsers often open multiple simultaneous connections to a web server to download multiple resources concurrently. All of those connections have the same server address, server port, and client address, but different client port.
If you want to have multiple simultaneous connections that are associated with one another in some way that goes beyond IP addresses, then you'll need to develop a protocol for it that involves multiple ports at at least one end. If the machines make reciprocal connections, with A connecting to B and then B connecting, separately, to A, then you'll need different ports on both sides. The port numbers to use might be fixed by the protocol or negotiated in some way, at your discretion, but the specifics described in the question are not an option.
I am writing UDP server and client in C on UNIX. I need to handle each client in its own thread on server. In each thread, I want to receive only messages from corresponding client. Right now I am peeking messages using recvfrom and checking message whether it is "mine".
I heard that it is possible to have multiple sockets listening on the same host:port and connect each of them to corresponding client so it will receive messages only from the said client. Here is the code I run when I run into new client. However, after first client connects messages are in fact filtered, but not only on new socket, but also on main socket listening for new clients, so I cant connect new clients.
void fun(int* sockfd, struct sockaddr_in* my_addr, struct sockaddr_in* cli_addr)){
if ((*sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
ERR("socket");
}
int optval = 1;
bzero(my_addr, sizeof (*my_addr));
my_addr->sin_family = AF_INET;
my_addr->sin_port = htons(PORT);
my_addr->sin_addr.s_addr = htonl(INADDR_ANY);
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval)) < 0) {
ERR("setsockopt");
}
if (bind(sockfd, (struct sockaddr*) my_addr, sizeof (*my_addr)) == -1) {
ERR("bind");
}
if (connect(*socket, (struct sockaddr*) cli_addr, sizeof (*cli_addr)) < 0)
ERR("connect");
}
}
Is there a better (and working) way to filter UDP messages?
In my opinion you should use one thread for receiving and sending data and then dispatch to the other threads.
There is no need for more than one socket server side. One socket receive all datagrams, you process them by extracting the source, and then dispatch it.
You could do something like this:
Datagram is read:
source is known, call the backback you have for it
source is not known, create a new thread, and register a callback for this source.
Whenever you want to "disconnect" a client, unregister the callback and remove the thread.
Note that by "disconnect" I mean in a logical way for your application, since UDP socket are not connected.
I'm trying to connect to a server I'm running in C on a computer on a wireless ad-hoc network. The problem is when I'm to connect from another computer on the network using telnet it doesn't work. I can ping the IP address (192.168.0.1) but using:
telnet 192.168.0.1 8889
results in the error "Connection Refused" (The server is listening on port 8889 which I've verified).
I've investigated further and found that setting up my ad-hoc network using network manager solves this problem. Currently I'm setting up my ad-hoc network via terminal and I would like to keep it this way. The ad-hoc network is being setup with the following commands:
sudo service network-manager stop
sudo iwconfig wlan0 mode ad-hoc essid 'rgd' channel AUTO key OFF
Where wlan0 is my wireless device.
I'm not sure why this error is occurring. Can anybody help me with this?
Edit: #Huygens netstat -tlpen displays the following
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 0.0.0.0:48727 0.0.0.0:* LISTEN 1000 302920 13098/socket
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 0 273220 933/cupsd
tcp 0 0 0.0.0.0:54880 0.0.0.0:* LISTEN 1000 304089 13148/socket
tcp 0 0 127.0.1.1:53 0.0.0.0:* LISTEN 0 12886 1606/dnsmasq
tcp6 0 0 ::1:631 :::* LISTEN 0 273219 933/cupsd
tcp6 0 0 ::1:54822 :::* LISTEN 1000 46736 3297/java
I don't see my server here for some reason :(
I've added the server code I'm running here for further reference:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c;
struct sockaddr_in server , client;
char *message;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8889 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (new_socket<0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Reply to the client
message = "Hello Client , I have received your connection. But I have to go now, bye\n";
write(new_socket , message , strlen(message));
return 0;
}
You have to do things in the proper order I think.
First you should set-up your network interfaces. Once done, you should check that you can ping your network interfaces and that if you have a firewall that it would allow incoming connection on port 8889. To see of you have a firewall activated: iptables -L if there are any rule, then you have a firewall. In addition, make sure that each network interface has the expected IP address: ifconfig.
For testing purpose and if you are on a safe network, you can temporarily disable the firewall: iptables -F (precede it by sudo if you require super user privilege).
Then, you can start your server. Check that it is up and running (via ps wux) and check that it is in listening mode via netstat -tlpen.
Now try to telnet to it via telnet 192.168.0.1 8889.
PS: Of course your ad-hoc network should be on a different subnet than your local network. So if you are using both your ethernet (cable) network and an ad-hoc wifi network, each should be on a different subnet: e.g. 192.168.0.1/24 and 192.168.1.1/24.
I'm working on a homework problem for class. I want to start a UDP Server that listens for a file request. It opens the file and sends it back to the requesting client with UDP.
Heres the server code.
// Create UDP Socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Can't create socket");
exit(-1);
}
// Configure socket
memset(&server, 0, sizeof server);
server.sin_family = AF_INET; // Use IPv4
server.sin_addr.s_addr = htonl(INADDR_ANY); // My IP
server.sin_port = htons(atoi(argv[1])); // Server Port
// Bind socket
if ((bind(sockfd, (struct sockaddr *) &server, sizeof(server))) == -1) {
close(sockfd);
perror("Can't bind");
}
printf("listener: waiting to recvfrom...\n");
if (listen(sockfd, 5) == -1) {
perror("Can't listen for connections");
exit(-1);
}
while (1) {
client_len = sizeof(struct sockaddr_in);
newsockfd = accept(sockfd, (struct sockaddr*)&client,&client_len);
if (newsockfd < 0) {
perror("ERROR on accept");
}
// Some how parse request
// I do I use recv or recvfrom?
// I do I make new UDP socket to send data back to client?
sendFile(newsockfd, filename);
close(newsockfd);
}
close(sockfd);
I'm kind of lost how do I recv data from the client? And how to I make a new UDP connection back to the client?
How UDP is different from TCP:
message-oriented, not stream-oriented. You don't read/write or send/recv. You sendto/recvfrom. The size of message is limited to 64K. Each call to recvfrom gets one message sent by a call to sendto. If recvfrom passes a buffer that's smaller than the size of message, the rest of message is gone for good.
no connections. Therefore no listen/accept/connect. You send a message to a particular address/port. When you receive message (on the address/port to which your socket is bound), you get the source of the incoming message as an output parameter to recvfrom.
no guarantees. The messages can be dropped or received out of order. If I remember correctly, they cannot be truncated, though.
One last word of caution - you may find yourself re-inventing TCP over UDP. In that case, stop and go back to TCP.
I have written a UDP server-client in C , where the client sends a registration number and the server gives a name as the feedback.
SERVER
0. Variable initialization
1. sock()
2. bind()
3. recvfrom()
4. sendto()
CLIENT
0. gethostbyname()
1. sock()
2. bzero()
4. sendto()
5. recvfrom()
Hope it helps. You can find the example code here udp server/client
accept is only used for connection oriented (STREAM) sockets. UDP is not stream, oriented, so there are no connections and you can't use accept(2) -- it will return EOPNOTSUPP.
Instead, you just read packets directly from the bound service socket (generally using recvfrom(2) so you can tell where thy came from, though you can use recv or just read if you don't care), afterwhich you can send packets back using the same socket (and generally using sendto(2))
Keep in mind that UDP is connectionless. It only sends packets, and is not suitable for sending files - unless the entire content fit in one UDP packet.
If you anyway want to send/receive UDP packets, you simply call sendto/recvfrom with the appropriate addresses.