Создание tcp сервера

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Yurakl
новенький
Сообщения: 62
Зарегистрирован: 20.01.2010 07:59:53

Создание tcp сервера

Сообщение Yurakl »

Добрый день. Мне необходимо чтобы с одного устройства(компьютера) передавались байты на другой компьютер. Tcp клиент есть, а вот возникла проблема в создании tcp сервера.
Пишу на lazarus под Linux

Код: Выделить всё

   s:=socket(AF_INET, SOCK_STREAM, 0);
    serv_addr.sin_family:= AF_INET;
    serv_addr.sin_addr.s_addr:= INADDR_ANY;
    serv_addr.sin_port:= htons(10001);
    bind(s, serv_addr, sizeof(serv_addr));
    listen(s, 3);

и на данном этапе выводится,что bind=false
Подскажите,пожалуйста
Yurakl
новенький
Сообщения: 62
Зарегистрирован: 20.01.2010 07:59:53

Сообщение Yurakl »

никто никогда не реализовывал??
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Yurakl писал(а):никто никогда не реализовывал??

очевидно же, что ты первый ;)

http://linux.die.net/man/2/bind

http://linux.die.net/man/2/listen

самая важное, что там написано:

Return Value

On success, zero is returned. On error, -1 is returned, and errno is set appropriately


наверное, следующий логический шаг начинать "принимать" сообщения, используя либо accept либо select?!
Yurakl
новенький
Сообщения: 62
Зарегистрирован: 20.01.2010 07:59:53

Сообщение Yurakl »

скалогрыз
accept наверное нужно использовать после того как привязка по bind пройдет

Код: Выделить всё

    s:=socket(AF_INET, SOCK_STREAM, 0);
    port:=10001;
      serv_addr.sin_family:= AF_INET;
      serv_addr.sin_addr.s_addr:= INADDR_ANY;
      serv_addr.sin_port:= htons(port);
      if bind(s, serv_addr, sizeof(serv_addr))=false then writeln(errno);
      if listen(s, 1)=false then writeln(errno);
      razmer_addr:=sizeof(saddr);
      p:=accept(s, saddr, razmer_addr);


C bind скорее всего разберусь, там вроде дело с портом, но далее accept выдает ошибки...
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

стёр сообщение?!?? :shock:

ну ладно... насчёт переиспользования адреса (может понадобиться кому, 2 сервера поднять на тот же порт): SO_REUSEADDR

http://linux.die.net/man/7/socket

вообще не используй bind() функции, используй fpbind()
Yurakl
новенький
Сообщения: 62
Зарегистрирован: 20.01.2010 07:59:53

Сообщение Yurakl »

скалогрыз писал(а):вообще не используй bind() функции, используй fpbind()

а чем fpbind лучше bind?
еще под lazarus в linux есть свои особенности....
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

а чем fpbind лучше bind?

fp* функции поддерживаются командой разработчиков FPC. можно считать их кросс-платформенными.
я сам не в курсе причин о введении fp* функций, но раз уж разработчики рекомендуют, то почему бы и нет ;)
Yurakl
новенький
Сообщения: 62
Зарегистрирован: 20.01.2010 07:59:53

Сообщение Yurakl »

Ну если с Bind вроде разобрался, встает проблема с accept.
Как я понимаю как раз на этой функции происходит непосредственная связь с клиентом. но почему то при запуске клиента, на accept все останавливается.
см. выше код
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Yurakl писал(а):Ну если с Bind вроде разобрался, встает проблема с accept.

и в чём же была проблема? неправильный порт?

Yurakl писал(а):Как я понимаю как раз на этой функции происходит непосредственная связь с клиентом. но почему то при запуске клиента, на accept все останавливается.
см. выше код

Accept - блокирует исполнения потока, если сокет находится в блокирующем режиме (как раз, как в коде выше).
Разблокируется только в том случае, если сервер-сокет закрыт, либо присоединился клиент.

если проблема была с портом, то нужно проверить клиентское приложение - туда ли коннектится.
Yurakl
новенький
Сообщения: 62
Зарегистрирован: 20.01.2010 07:59:53

Сообщение Yurakl »

все,я решил проблему. Сейчас осталось только сделать, чтобы сервер получал подтверждение переданных байтов и потом переходить к следующему этапу...
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Очень продуктивное описание! Людям пригодится твой опыт!
Аватара пользователя
Verx0Laz
постоялец
Сообщения: 125
Зарегистрирован: 11.09.2007 11:24:07

Сообщение Verx0Laz »

Yurakl писал(а):все,я решил проблему. Сейчас осталось только сделать, чтобы сервер получал подтверждение переданных байтов и потом переходить к следующему этапу...


А теперь пора подумать о вечном :) Просьба к тебе огромная - помоги фронту, природе и будущим поколениям - выложи упрощенные, но рабочие исходнички клиента и сервера, и желательно с комментариями. Этим ты придашь святости облику своему, а заодно и будущих кодеров на путь истинный наставишь. Но главное - сильно занятые шаманы на подобное подтягиваются гораздо охотнее, и часто при этом подсказывают, что можно красивее реализовать, а где заставить код шуршать быстрее. В общем, дело достаточно богоугодное :)
Yurakl
новенький
Сообщения: 62
Зарегистрирован: 20.01.2010 07:59:53

Сообщение Yurakl »

Вот tcp сервер

Код: Выделить всё

s:=socket(AF_INET, SOCK_STREAM, 0);
    port:=10001;
      serv_addr.sin_family:= AF_INET;
      serv_addr.sin_addr.s_addr:= INADDR_ANY;
      serv_addr.sin_port:= htons(port);
      if bind(s, serv_addr, sizeof(serv_addr))=false then writeln(errno);
      if listen(s, 1)=false then writeln(errno);
  ac:=true;
  razmer_addr:=sizeof(saddr);
    while ac do
      begin
      p:=accept(s, saddr, razmer_addr);
     writeln(p);
        if p<0 then writeln(errno);
   while ac do
     begin
   send(p,buf[0],5,MSG_DONTWAIT);
    sleep(2500);
    end;
   closesocket(p);
   end;
   ac:=false;


Добавлено спустя 19 минут 25 секунд:
подскажите, пожалуйста, как сервер может получить подтверждение о том,что отправленные байты дошли до получателя, т.е. связь по ethernet есть
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Yurakl писал(а):подскажите, пожалуйста, как сервер может получить подтверждение о том,что отправленные байты дошли до получателя, т.е. связь по ethernet есть

никак! Клиент должен отписаться серваку, о том что байты получены.
Yurakl
новенький
Сообщения: 62
Зарегистрирован: 20.01.2010 07:59:53

Сообщение Yurakl »

Кстати команда send возвращает количество переданных символов!и если клиент отрублен, то соответственно она возвратит -1.
Ответить