Linux udp socket listen

Server udp c linux

Programming UDP sockets in C on Linux – Client and Server example

UDP sockets

This article describes how to write a simple echo server and client using udp sockets in C on Linux/Unix platform.

UDP sockets or Datagram sockets are different from the TCP sockets in a number of ways. The most important difference is that UDP sockets are not connection oriented. More technically speaking, a UDP server does not accept connections and a udp client does not connect to server. The server will bind and then directly receive data and the client shall directly send the data.

Simple UDP Server

socket() -> bind() -> recvfrom() -> sendto() Run the above code by doing a gcc server.c && ./a.out at the terminal. Then it will show waiting for data like this Next step would be to connect to this server using a client. We shall be making a client program a little later but first for testing this code we can use netcat. Test the server with netcat Open another terminal and connect to this udp server using netcat and then send some data. The same data will be send back by the server. Over here we are using the ncat command from the nmap package. Note : We had to use netcat because the ordinary telnet command does not support udp protocol. The -u option of netcat specifies udp protocol. Check open port with netstat

The netstat command can be used to check if the udp port is open or not. Note the *:8888 entry of output. Thats our server program.
The entry that has localhost:8888 in «Foreign Address» column, indicates some client connected to it, which is netcat over here.

UDP Client

Now that we have tested our server with netcat, its time to make a client and use it instead of netcat.
The program flow is like Here is a quick example ‘, BUFLEN); //try to receive some data, this is a blocking call if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1) puts(buf); > close(s); return 0; > Run the above program and it will ask for some message Whatever message the client sends to server, the same comes back as it is and is echoed.

Conclusion

UDP sockets are used by protocols like DNS etc. The main idea behind using UDP is to transfer small amounts of data and where reliability is not a very important issue. UDP is also used in broadcasting/multicasting. When a file transfer is being done or large amount of data is being transferred in parts the transfer has to be much more reliable for the task to complete. Then the TCP sockets are used. A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at [email protected] .

Читайте также:  Get chrome version linux

15 thoughts on “ Programming UDP sockets in C on Linux – Client and Server example ”

I’m a not a programmer but are very interested in electronics and making things automated. This was very helpful example of udp socket communications. What I did find though was the program doesn’t do anything else whilst it waits for data. How would you suggest to say send this server “Blink Led 1” and continue to listen for commands to turn on, blink or turn off leds.
I can for example blink the led no problem in one project, I can get you code also running on a pi and responding to commands I send it now but I would like to be able to continue doing things in the background. Thanks for you time. i haven’t done sockets for a long time. right now i can think of using multiple threads do things in parallel.
so the main thread could do its background work, and an extra thread could listen to the udp port for incoming messages.
or the other way round.
but i am not sure if that is the best approach. there might be better alternatives. Silver Moon’s approach will work but the best way would be to listen for socket connections asynchronously using epoll() and using TCP not UDP, UDP is unreliable so some of your commands might not make it to the server as intended. That’s what is done in most modern socket servers. Try googling how to use epoll() (Linux system call so should work on Raspberry Pi). It will allow you to have an efficient and scalable socket server. (I am actually almost done developing an IoT socket communication system myself using raspberry pi as main server and epoll() with TCP is the best approach for this kind of stuff as far as I know.

Thx! This article was really helpful for understanding some basic things about socket programming. Thank you so much for this, it was really helpful! update note: Ubuntu 16.04.3. gcc 5.4.0 complained until slen was declared unsigned int. And ncat used option -vv which on my Ubuntu system means verbose. The captured text does not have the verbose output. My system had five lines of information for each line of typed in data.
Still, I am new to Linux and Ubuntu and this is an unexpected cool way to test the server app.
Thank you. Very helpful. Thanks! Hi, I am new to socket programminga and linux , can you tell me … can we turn a system into a server ? and do communication using above programming? can we establish communication on the microcontroller using above programs? Excelent example, thanks very much!
I’ve found that it needs only a tiny addition.
To clean the buffer on the server also. So just adding on Server:

Источник

listen for returning UDP packets in bash

I played around with bash(4.0.33) network support for learning purposes and tried to create a port scanner in bash. For TCP I opened a TCP/IP socket with exec 3<>/dev/tcp/192.0.2.1/80 and appropriate action was taken if the connection was refused or connect system call timed out. However, with UDP I’m easily able to send a packet with echo > /dev/udp/192.0.2.1/53 but how to read returning packets from correct socket? I mean UDP datagram sent to 192.0.2.1 has source port from ephemeral port range and thus I do not know which socket in /dev/udp/192.0.2.1/ directory should I read. Or isn’t this doable without external utilities like tcpdump?

no offence, but even though you say this is for learning purposes, what’s the point of learning something if you’re never going to use it? bash is definitely not the right choice for this.

Читайте также:  Linux wifi mini pci

@KarolyHorvath Actually, bash is an excellent tool for small and tiny IOT devices, bash handles UDP pretty well for many applications. and, BTW that was not the question: he was not asking for opinion.

2 Answers 2

Bash’s UDP support isn’t great, and is compiled out on many distros (Debian/Ubuntu and derivatives especially). The recommended tool is netcat:

Note: Use coproc or named pipes to read and write from the same netcat process. Don’t send a packet first and try to catch the reply netcat.

Bash is really the wrong language for this though. Consider using Python, which handles both UDP and binary data way better, with just a couple of more lines of code.

Could you explain the usage of named pipe in this case? Did you mean to write UDP packet into named pipe and then use the named pipe as stdin for nc ? If yes, then why is this approach better than redirecting UDP packet directly into nc ?

You can use coprocs or named pipes for bidirectional communication with a process. If you just want to send one packet and receive one reply, you don’t need it.

«bash is definitely not the right choice for this»
«Bash is really the wrong language for this though»
Not sure why this is asserted (depending on disto). This works for me on a pi-Z-W:

#!/bin/bash while true; do nc -lu 16523 | (read line; echo $line cmd=$ echo $cmd if [ "$cmd" == "Send Date" ] ; then dt="!!D$(date +%y%m%d)" echo $dt > /dev/udp/192.168.2.165/16523 elif [ "$cmd" == "Send Time" ] ; then tm="!!T$(date +%H%M%S)" echo $tm echo $tm > /dev/udp/192.168.2.165/16523 else sleep 1s echo $line >> /home/pi/udp16523.log fi) done 

Then another process can, say hourly, send the time with
echo «!!T$(date +%H%M%S)» > /dev/udp/192.168.2.165/16523

I did have to turn off history expansion with «set H+» in /etc/rc.local to handle the unexpected (by me) expansion of ! within quotes.

Источник

Русские Блоги

UDP означает протокол пользовательских дейтаграмм, который представляет собой протокол передачи без установления соединения. По сравнению с TCP, его преимущества и недостатки:

Преимущества: высокая скорость передачи, низкое потребление ресурсов, простое программирование, широко используется при передаче аудио- и видеоданных.

Недостатки: при низком качестве сети потеря пакетов будет серьезной, что приведет к потере или повреждению данных.

Процесс общения

Поскольку UDP не требует установления соединения, процесс связи будет немного отличаться:

Как видно из рисунка, использование UDP для связи позволяет осуществлять прямую связь без установления соединения между обеими сторонами.

Два, функция API

Используйте UDP для сетевого программирования, Linux также предоставляет некоторые функции.

Читайте также:  Graphics program in linux

2.1 sendto отправка

Это функция отправки данных, используемая в режиме UDP.Отличие от режима TCP состоит в том, что для каждой отправки требуется такая информация, как адрес назначения.

#include  #include  ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); 
  • sockfd: дескриптор файла сокета.
  • buf: отправленный контент.
  • len: длина отправленных данных.
  • flags: flags, вы можете использовать этот параметр для установки различных методов передачи данных, обычно используйте 0.
  • dest_addr: информация об адресе назначения, инкапсулированная в структуре socketaddr.
  • addrlen: размер информации о целевом адресе.
  • Возвращаемое значение: вернуть количество отправленных байтов в случае успеха, -1 в случае неудачи и установить для соответствующей ошибки значение errno.

2.2 recvfrom получения

#include  #include  ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); 
  • sockfd: дескриптор файла сокета.
  • buf: буфер данных, используемый для хранения полученных данных.
  • len: длина получаемых данных.
  • flags: flags, вы можете использовать этот параметр для установки различных методов передачи данных, обычно используйте 0.
  • src_addr: информация об адресе источника, инкапсулированная в структуре socketaddr.
  • addrlen: размер информации об адресе источника,указатель
  • Возвращаемое значение: вернуть количество байтов, полученных в случае успеха, -1 в случае неудачи и установить для соответствующей ошибки значение errno.

См. Другие функции в предыдущем блоге:

Три, пример связи UDP

client.c (сначала отправить):

#include #include  #include  #include #include  #include typedef struct sockaddr* saddrp; int main(int argc, char const *argv[])  int sockfd = socket(AF_INET,SOCK_DGRAM,0); if (0 > sockfd)  perror("socket"); return -1; > struct sockaddr_in addr = >; addr.sin_family = AF_INET; addr.sin_port = htons(12345); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); socklen_t addr_len = sizeof(struct sockaddr_in); while(1)  char buf[255] = >; printf("Please input cData:"); gets(buf); sendto(sockfd,buf,strlen(buf)+1,0,(saddrp)&addr,sizeof(addr)); if(0 == strncmp(buf, "end", 3)) break; recvfrom(sockfd,buf,sizeof(buf),0,(saddrp)&addr,&addr_len); printf("cRecv:%s\n",buf); printf("the ipaddr = %#x\n", addr.sin_addr.s_addr); printf("the port = %d\n", addr.sin_port); if(0 == strncmp(buf, "end", 3)) break; > close(sockfd); return 0; > 

server.c (сначала получить):

#include #include #include  #include  #include #include  typedef struct sockaddr* saddrp; int main(int argc, char const *argv[])  // Создаем сокет int sockfd = socket(AF_INET,SOCK_DGRAM,0); if (0 > sockfd)  perror("sockfd"); return -1; > // Подготавливаем адрес struct sockaddr_in addr = >; addr.sin_family = AF_INET;//ipv4 addr.sin_port = htons(12345);// Номер порта addr.sin_addr.s_addr = htonl(INADDR_ANY);// Получаем ip автоматически // Привязка int ret = bind(sockfd,(saddrp)&addr,sizeof(addr)); if (0 > ret)  perror("bind"); return -1; > struct sockaddr_in src_addr =>; socklen_t addr_len = sizeof(struct sockaddr_in); while(1)  char buf[255] = >; // Получение данных и IP-адреса источника recvfrom(sockfd,buf,sizeof(buf),0,(saddrp)&src_addr,&addr_len); printf("sRecv:%s\n",buf); if (0 == strncmp(buf,"end",3)) break; // Отправляем данные на целевой адрес printf("Please input sData to send:"); gets(buf); sendto(sockfd,buf,strlen(buf)+1,0,(saddrp)&src_addr,addr_len); if (0 == strncmp(buf,"end", 3)) break; > // Закрываем объект сокета close(sockfd); return 0; > 

результат операции:

client:

server:

анализ:

Клиент сначала отправляет данные на сервер. После того, как область обслуживания получает данные, она знает адресную информацию клиента, а затем данные могут быть отправлены клиенту. Как правило, клиент отправляет данные первым, а сервер первым их получает. Введите конец, и обе стороны будут судить о конце.

Источник

Оцените статью
Adblock
detector