Меню Рубрики

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

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] .

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:

//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

Источник

Клиент-сервер под linux на c++ общение клиентов «все со всеми» с использованием потоков

Начну с того, что была предложена работа на должность программиста с\с++. Задание это название темы.

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

После всего этого в клиенте нужно отправить сообщение серверу используя функции send или write а на стороне сервера принять сообщение и переотправить его обратно клиенту используя функции read и send.

Вообще есть разные функции отправки и приема, к примеру send и recv вместе с сообщением шлют еще и флаг подтверждения, а функции read и write не требуют подтверждения, то есть сообщение может потерять байты при отправке и это не будет зафиксировано.

Так как сокеты это дуплекс и создавая связь между клиентом и сервером мы не можем писать туда сообщения из других подключенных сокетов, необходимо создать массив со всеми активными сокетами подключенными к серверу. И еще одно замечание очень важное:

Для общения между несколькими сокетами необходимо использовать функцию select, которая выбирает сокет из списка и отсылает ему сообщение, и так далее, пока не закончатся все записанные сокеты

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

Запишем все это в функцию и создадим отдельный поток:

Что касаемо клиента, то необходимо создать два разных потока для чтения и записи в сокет:

Теперь все работает. Спасибо за снимание. Надеюсь что это пригодится тем, кто так же как и я пытался написать клиент-сервер, но не смог найти нужную информацию в сети.

Ой, у вас баннер убежал!

Редакторский дайджест

Присылаем лучшие статьи раз в месяц

Скоро на этот адрес придет письмо. Подтвердите подписку, если всё в силе.

Похожие публикации

Как починить «сломанный» VPS сервер на Linux

Акция «Лето KVM» — Виртуальный сервер на Linux

LTSP: Терминальный сервер на Linux

Средняя зарплата в IT

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Комментарии 35

Недостаток такой реализации — это однопоточность сервера. Если хоть какое-то соединение с клиентом «подвиснет» и будет переполнен его исходящий буфер, то сервер просто зависнет на вызове write.

Решения данной проблемы:
1. Создание отдельного потока для каждого клиента. Недостаток: необходимость понимания механизмов синхронизации, низкая эффективность при большом числе соединений. Новичкам будет тяжело разобраться.
2. Использование select также и для записи в сокеты. Думаю, в данном случае самое простое решение.
3. Использование более высокоуровневых языков с поддержкой асинхронного программирования.

Вообще есть разные функции отправки и приема, к примеру send и recv вместе с сообщением шлют еще и флаг подтверждения, а функции read и write не требуют подтверждения, то есть сообщение может потерять байты при отправке и это не будет зафиксировано.

Это не так: read() и write() эквивалентны recv() и send() с нулевыми флагами.

Ну и ещё один момент: код очень разрозненный, фрагментарный. Новичку была бы полезна ссылка на репозиторий.

Источник

Реализация 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,

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

  • Переустановка mac os sierra с нуля
  • Переустановка mac os macbook air
  • Переустановка mac os high sierra
  • Переустановить mac os x требует apple id
  • Переустановить mac os x с удалением всех данных