Linux udp client server c

Реализация UDP сервера-клиента в C

Существует два основных протокола транспортного уровня для связи между хостами: TCP и UDP . Создание TCP-сервера / клиента обсуждалось в предыдущем посте .

теория
В UDP клиент не устанавливает соединение с сервером, как в TCP, а просто отправляет дейтаграмму. Точно так же сервер не должен принимать соединение и просто ожидает прибытия дейтаграмм. Датаграммы по прибытии содержат адрес отправителя, который сервер использует для отправки данных нужному клиенту.

Весь процесс можно разбить на следующие этапы:
UDP-сервер:

  1. Создать UDP-сокет.
  2. Свяжите сокет с адресом сервера.
  3. Подождите, пока пакет дейтаграммы не будет получен от клиента.
  4. Обработайте пакет дейтаграммы и отправьте ответ клиенту.
  5. Вернитесь к шагу 3.

UDP-клиент:

  1. Создать UDP-сокет.
  2. Отправить сообщение на сервер.
  3. Подождите, пока ответ от сервера не будет получен.
  4. Обработайте ответ и при необходимости вернитесь к шагу 2.
  5. Закройте дескриптор сокета и выйдите.

Необходимые функции:

Аргументы:
домен — определяет связь
домен (AF_INET для IPv4 / AF_INET6 для IPv6)
тип — тип сокета, который будет создан
(SOCK_STREAM для TCP / SOCK_DGRAM для UDP)
протокол — протокол, который будет использоваться сокетом.
0 означает использовать протокол по умолчанию для семейства адресов.

Аргументы:
sockfd — дескриптор файла сокета, который будет связан
addr — структура, в которой указан адрес для привязки
addrlen — размер структуры адреса

Аргументы:
sockfd — файловый дескриптор сокета
buf — буфер приложения, содержащий данные для отправки
len — Размер буфера приложения buf
flags — Побитовое ИЛИ флагов для изменения поведения сокета
dest_addr — структура, содержащая адрес назначения
addrlen — размер структуры dest_addr

Аргументы:
sockfd — файловый дескриптор сокета
buf — буфер приложения, в который нужно получать данные
len — Размер буфера приложения buf
flags — Побитовое ИЛИ флагов для изменения поведения сокета
src_addr — возвращается структура, содержащая адрес источника
addrlen — переменная, в которой возвращается размер структуры src_addr

Аргументы:
fd — дескриптор файла

В приведенном ниже коде показан обмен одним приветственным сообщением между сервером и клиентом для демонстрации модели.

// Серверная реализация модели клиент-сервер UDP
#include
#include
#include
#include
#include
#include
#include
#include

#define PORT 8080
#define MAXLINE 1024

char *hello = «Hello from server» ;

struct sockaddr_in servaddr, cliaddr;

// Создание дескриптора файла сокета

if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0))

perror ( «socket creation failed» );

// Заполнение информации о сервере

servaddr.sin_family = AF_INET; // IPv4

// Привязываем сокет с адресом сервера

if ( bind(sockfd, ( const struct sockaddr *)&servaddr,

perror ( «bind failed» );

len = sizeof (cliaddr); // len is value / resuslt

n = recvfrom(sockfd, ( char *)buffer, MAXLINE,

MSG_WAITALL, ( struct sockaddr *) &cliaddr,

printf ( «Client : %s\n» , buffer);

sendto(sockfd, ( const char *)hello, strlen (hello),

MSG_CONFIRM, ( const struct sockaddr *) &cliaddr,

printf ( «Hello message sent.\n» );

// Клиентская реализация модели клиент-сервер UDP
#include
#include
#include
#include
#include
#include
#include
#include

#define PORT 8080
#define MAXLINE 1024

char *hello = «Hello from client» ;

struct sockaddr_in servaddr;

// Создание дескриптора файла сокета

if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0))

perror ( «socket creation failed» );

// Заполнение информации о сервере

sendto(sockfd, ( const char *)hello, strlen (hello),

MSG_CONFIRM, ( const struct sockaddr *) &servaddr,

printf ( «Hello message sent.\n» );

n = recvfrom(sockfd, ( char *)buffer, MAXLINE,

MSG_WAITALL, ( struct sockaddr *) &servaddr,

Источник

UDP Server-Client implementation in C

There are two major transport layer protocols to communicate between hosts : TCP and UDP. Creating TCP Server/Client was discussed in a previous post.

Theory
In UDP, the client does not form a connection with the server like in TCP and instead just sends a datagram. Similarly, the server need not accept a connection and just waits for datagrams to arrive. Datagrams upon arrival contain the address of sender which the server uses to send data to the correct client.

The entire process can be broken down into following steps :
UDP Server :

  1. Create UDP socket.
  2. Bind the socket to server address.
  3. Wait until datagram packet arrives from client.
  4. Process the datagram packet and send a reply to client.
  5. Go back to Step 3.

UDP Client :

  1. Create UDP socket.
  2. Send message to server.
  3. Wait until response from server is received.
  4. Process reply and go back to step 2, if necessary.
  5. Close socket descriptor and exit.
Читайте также:  Hollow knight для linux

Necessary Functions :

Arguments :
domain – Specifies the communication
domain ( AF_INET for IPv4/ AF_INET6 for IPv6 )
type – Type of socket to be created
( SOCK_STREAM for TCP / SOCK_DGRAM for UDP )
protocol – Protocol to be used by socket.
0 means use default protocol for the address family.

Arguments :
sockfd – File descriptor of socket to be binded
addr – Structure in which address to be binded to is specified
addrlen – Size of addr structure

Arguments :
sockfd – File descriptor of socket
buf – Application buffer containing the data to be sent
len – Size of buf application buffer
flags – Bitwise OR of flags to modify socket behaviour
dest_addr – Structure containing address of destination
addrlen – Size of dest_addr structure

Arguments :
sockfd – File descriptor of socket
buf – Application buffer in which to receive data
len – Size of buf application buffer
flags – Bitwise OR of flags to modify socket behaviour
src_addr – Structure containing source address is returned
addrlen – Variable in which size of src_addr structure is returned

Arguments :
fd – File descriptor

In the below code, exchange of one hello message between server and client is shown to demonstrate the model.

Источник

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

So lets first make a very simple ECHO server with UDP socket. The flow of the code would be

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) < die("recvfrom()"); >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] .

Читайте также:  Macbook air a1237 установка mac os catalina

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

Hello. You seem to have double pasted the second code sample inside itself. THanks for the tutorial

Hey Silver Moon,

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:

//keep listening for data
while(1)
<
printf(“Waiting for data…”);
fflush(stdout);
memset(buf,’\0′, BUFLEN); //Add this line

if that sent character, how about send some file, example a picture, how to change in the script character sent to picture sent.

Please remove gets in Client:46 with:
fgets(message, BUFLEN, stdin);

What if the data sent from client side having some different Server address, SERVER 192.168.16.30 (this IP is pingable)

how to pass array , vector etc. between client and server?

if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1)

here &slen should be (socklen_t*)&slen . and work perfectly. Thank u

Источник

UDP made simple

Abstract: This page describes how to write a simple UDP client/server system in a C/Unix environment. The code is explained step by step.

Motivation: I needed a page like this when working with a small test program for my master’s thesis at Appius / Fдlt Communications. It is quite hard to remember all the socket API details off the top of your head, so I wanted a small reference page to get me started quickly without having to wade through tons of man pages. As I did not find a page I liked, I decided to write one. I hope it will be useful for others, too.

Читайте также:  Самопроизвольно отключается wifi windows 10

Caveats: The code is known to work under recent (fall 1999) versions of Linux. It should work on other Unices too, though some of the header files may be located in other directories on your system.

The server

Comments

  • Lines 8-10 define the buffer size (quite arbitrary), the number of packets to receive and the UDP port number to listen at. You could use any port number above 1023, although bind() will fail if someone else is using the same port simultaneously.
  • The function diep() is used for error handling.
  • 21: Declare receive buffer.
  • 22: sockaddr_in is a structure containing an Internet socket address. Basically, it contains:
    • an address family (always AF_INET for our purposes)
    • a port number
    • an IP address

    si_me defines the socket where the server will listen. si_other defines the socket at the other end of the link (that is, the client).

  • 24: Create a socket. AF_INET says that it will be an Internet socket. SOCK_DGRAM says that it will use datagram delivery instead of virtual circuits. IPPROTO_UDP says that it will use the UDP protocol (the standard transport layer protocol for datagrams in IP networks). Generally you can use zero for the last parameter; the kernel will figure out what protocol to use (in this case, it would choose IPPROTO_UDP anyway).
  • 27: We need to initialize the si_me structure. The first step is to fill it with binary zeroes, which is done on this line. (I doubt this step is actually necessary in modern Unix implementations, but better safe than sorry.)
  • 28: We will use Internet addresses.
  • 29: Here, the port number is defined. htons() ensures that the byte order is correct (Host TO Network order/Short integer).
  • 30: This line is used to tell what IP address we want to bind to. Most machines have more than one network interface (for example, 127.0.0.1 for the loopback interface and some other address for the network card; there may be more than one network card). In the general case, you want to accept packets from any interface, so you use INADDR_ANY instead of a specific address.
  • 31: Now we are ready to bind the socket to the address we created above. This line tells the system that the socket s should be bound to the address in si_me .
  • 35: This call says that we want to receive a packet from s , that the data should be put info buf , and that buf can store at most BUFLEN characters. The zero parameter says that no special flags should be used. Data about the sender should be stored in si_other , which has room for slen byte. Note that recvfrom() will set slen to the number of bytes actually stored. If you want to play safe, set slen to sizeof(si_other) after each call to recvfrom() .
  • 37: The information about the sender we got from recvfrom() is displayed (IP:port), along with the data in the packet. inet_ntoa() takes a struct in_addr and converts it to a string in dot notation, which is rather useful if you want to display the address in a legible form.

The client

Note: The client is quite similar to the server. Only the differences will be discussed.

  • 1: You need to know the IP address of the machine where the server runs. If you run the client and the server on the same machine, try 127.0.0.1. «999.999.999.999» is not a legal IP address; you need to substitute your own server’s address.
  • 12: You may call bind() after the call to socket() , if you wish to specify which port and interface that should be used for the client socket. However, this is almost never necessary. The system will decide what port and interface to use.
  • 13-19: Here, we set up a sockaddr_in corresponding to the socket address where the server is listening. inet_aton() is used to convert a string in dotted-decimal ASCII notation to a binary address.
  • 24: Send BUFLEN bytes from buf to s , with no flags ( 0 ). The receiver is specified in si_other , which contains slen byte.

Источник

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