Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа с сокетами.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Jenya7
Пишу на vxWorks но наверно это не важно. Принцип везде одинаков.
Создаю сокет и пытаюсь подключиться к серверу. Сервером выступает компьютер.
На компьютере запускаю Hercules -> TCP Server -> Port 8200 (SERVER_PORT_NUM) -> Listen. Сервер бежит.

На стороне прибора
Код
STATUS TCP_ClientConnect (char *serverName, int *soc_desc)
{
    struct sockaddr_in  serverAddr;    /* server's socket address */
    int                 sockAddrSize;  /* size of socket address structure */
    int                 sFd;           /* socket file descriptor */

    /* create client's socket */
    if ((sFd = socket (AF_INET, SOCK_STREAM, 0)) == ERROR)
    {
        //perror ("socket");
        printf ("SOCKET ERROR\n");
        return (ERROR);
    }

    /* bind not required - port number is dynamic */
    /* build server socket address */
    sockAddrSize = sizeof (struct sockaddr_in);
    bzero ((char *) &serverAddr, sockAddrSize);
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_len = (u_char) sockAddrSize;
    serverAddr.sin_port = htons (SERVER_PORT_NUM);

    if (((int)(serverAddr.sin_addr.s_addr = inet_addr (serverName)) == ERROR) &&
        ((int)(serverAddr.sin_addr.s_addr = hostGetByName (serverName)) == ERROR))
    {
        printf ("UNKNOWN SERVER NAME\n");
        close (sFd);
        return (ERROR);
    }
    
    /* bind a port number to the socket */
    if (bind(sFd, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) == ERROR)
    {
        printf("BIND ERROR\n");
        return (ERROR);
    }

    /* connect to server */
    if (connect (sFd, (struct sockaddr *) &serverAddr, sockAddrSize) != OK)
    {
        printf ("CONNECTION ERROR\n");
        close (sFd);
        return (ERROR);
    }
    
    *soc_desc = sFd;
    
    return (OK);
}

И запускаю таск
Код
int socket_descriptor=0;
char *server_ip = "10.0.0.80";

void tSpectraTaskEntryPoint()
{
    
    if (TCP_ClientConnect(server_ip, &socket_descriptor)==ERROR)
     printf ("CLIENT CONNECT ERROR\n");
    else
    printf("CLIENT CONNECT OK descriptor = %d\n", socket_descriptor);
    
   SpectraMain();
}

Получаю ошибку
BIND ERROR
CLIENT CONNECT ERROR
Значит не выполняется привязка сокета к серверу? Я что то не так делаю?
Jenya7
модифицировал функцию чтоб выводить информацию.
Код
STATUS TCP_ClientConnect (char *serverName, int *soc_desc)
{
    struct sockaddr_in  serverAddr;    /* server's socket address */
    int                 sockAddrSize;  /* size of socket address structure */
    int                 sFd;           /* socket file descriptor */

    /* create client's socket */
    if ((sFd = socket (AF_INET, SOCK_STREAM, 0)) == ERROR)
    {
        printf ("SOCKET ERROR\n");
        return (ERROR);
    }
    else
         printf ("SOCKET DESC = %d\n", sFd);

    /* bind not required - port number is dynamic */
    /* build server socket address */
    sockAddrSize = sizeof (struct sockaddr_in);
    bzero ((char *) &serverAddr, sockAddrSize);
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_len = (u_char) sockAddrSize;
    serverAddr.sin_port = htons (SERVER_PORT_NUM);

    if (((int)(serverAddr.sin_addr.s_addr = inet_addr (serverName)) == ERROR) &&
        ((int)(serverAddr.sin_addr.s_addr = hostGetByName (serverName)) == ERROR))
    {
        printf ("UNKNOWN SERVER NAME\n");
        close (sFd);
        return (ERROR);
    }
    else
    {
        printf ("ADDR = %d\n", serverAddr.sin_addr.s_addr);
        printf ("PORT = %d\n", serverAddr.sin_port);
        
    }
    
    /* bind a port number to the socket */
    if (bind(sFd, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) == ERROR)
    {
        printf("BIND ERROR\n");
        return (ERROR);
    }


    /* connect to server */
    if (connect (sFd, (struct sockaddr *) &serverAddr, sockAddrSize) != OK)
    {
        printf ("CONNECTION ERROR\n");
        close (sFd);
        return (ERROR);
    }
    
    *soc_desc = sFd;
    
    return (OK);
}

вижу
SOCKET DESC = 26
ADDR = 1342177290
PORT = 2080
BIND ERROR
CLIENT CONNECT ERROR

перевожу 1342177290 в ИП аддресс получается 80.0.0.10 - перевернутый. порт тоже - вместо 8200 - 2080.
des333
Цитата(Jenya7 @ Sep 13 2017, 17:45) *
перевожу 1342177290 в ИП аддресс получается 80.0.0.10 - перевернутый. порт тоже - вместо 8200 - 2080.


И какой вывод можно получить?
gerber
Клиентский сокет можно не bind-ить, так как порт выделяется динамически, у вас же это и написано в комментариях.
bind на клиенте нужен, если вы хотите привязать сокет к конкретному локальному интерфейсу и порту.
У вас же идет bind к удаленному адресу и порту, что, конечно же, ни в какие ворота...
Jenya7
Цитата(gerber @ Sep 13 2017, 20:04) *
Клиентский сокет можно не bind-ить, так как порт выделяется динамически, у вас же это и написано в комментариях.
bind на клиенте нужен, если вы хотите привязать сокет к конкретному локальному интерфейсу и порту.
У вас же идет bind к удаленному адресу и порту, что, конечно же, ни в какие ворота...

но я хочу чтоб сокет обращался к серверу по его IP - 10.0.0.80 И порту 8200. Я не должен указать сокету куда обращаться? Это какой то бродкаст получается.

убрал байндинг и заработало.
проверяю
Код
void SpectraMain()
{
    while (spectra_alive)
    {
        if (TCP_ClientRead(read_buf, socket_descriptor) != ERROR)
        {
            printf ("CLIENT RECIEVED MESSAGE\n");
            //echo back
            TCP_ClientWrite(read_buf, socket_descriptor);
        }
        else
        {
            TCP_ClientWrite("no message", socket_descriptor);
        }
            
        taskDelay(50);
    }
}

на Hercules -> TCP Server посылаю строку - получаю CLIENT RECIEVED MESSAGE + строку.
спасибо.
gerber
Цитата(Jenya7 @ Sep 13 2017, 18:09) *
но я хочу чтоб сокет обращался к серверу по его IP - 10.0.0.80 И порту 8200. Я не должен указать сокету куда обращаться? Это какой то бродкаст получается.

В это невозможно поверить, но для этого есть функция connect() biggrin.gif
Jenya7
Тут возникает такой вопрос. Если связь с сервером прервалась? Что делать? Периодически проверять связь с сервером? А сокет? Он жив пока его не закрыли? Или надо проверять и его?
Эдди
Все надо проверять. Здесь я намучился с этими чертовыми сокетами! Сокет - не файл, запись в закрытый с другой стороны сокет никаких ошибок не даст! Поэтому нужно вводить таймауты и/или периодические рукопожатия.
Jenya7
Цитата(Эдди @ Sep 14 2017, 12:11) *
Все надо проверять. Здесь я намучился с этими чертовыми сокетами! Сокет - не файл, запись в закрытый с другой стороны сокет никаких ошибок не даст! Поэтому нужно вводить таймауты и/или периодические рукопожатия.

я понял. а как проверять? периодически делать if (connect (sFd, (struct sockaddr *) &serverAddr, sockAddrSize) != OK) или можно как то более красиво?
а сокет как проверить? if (socket_descriptor != 0) ?
Сергей Борщ
Все уже придумано за нас. Почитайте про SO_KEEPALIVE. Там по умолчанию довольно большие таймауты, но вы можете установить свои.
Jenya7
Цитата(Сергей Борщ @ Sep 14 2017, 13:01) *
Все уже придумано за нас. Почитайте про SO_KEEPALIVE. Там по умолчанию довольно большие таймауты, но вы можете установить свои.

нашел такой пример
Код
/* Set the option active */
   optval = 1;
   optlen = sizeof(optval);
   if(setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
      perror("setsockopt()");
      close(s);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE set on socket\n");

это чтоб включить SO_KEEPALIVE. компилируется без ошибок.
а как теперь проверить жив сокет или нет?

я так понимаю с выставленной опцией где то бежит проверка каждые tcp_keepalive_intvl и наверно выставляется флаг гдето в статусном регистре, который надо проверять.

Цитата
The SO_KEEPALIVE option causes a packet (called a 'keepalive probe')
to be sent to the remote system if a long time (by default, more than
2 hours) passes with no other data being sent or received. This packet
is designed to provoke an ACK response from the peer. This enables
detection of a peer which has become unreachable (e.g. powered off or
disconnected from the net).

а где я вижу этот ACK response from the peer?

Цитата(Эдди @ Sep 14 2017, 12:11) *
Все надо проверять. Здесь я намучился с этими чертовыми сокетами! Сокет - не файл, запись в закрытый с другой стороны сокет никаких ошибок не даст! Поэтому нужно вводить таймауты и/или периодические рукопожатия.

у меня этот код компилируется.
Код
static int waittoread(int sock){
    fd_set fds, efds;
    struct timeval timeout;
    int rc;
    timeout.tv_sec = 1; // wait not more than 1 second
    timeout.tv_usec = 0;
    FD_ZERO(&fds);
    FD_ZERO(&efds);
    FD_SET(sock, &fds);
    FD_SET(sock, &efds);
    do{
        rc = select(sock+1, &fds, NULL, &efds, &timeout);
        if(rc < 0){
            if(errno != EINTR){
                putlog("Server not available");
                WARN("select()");
                return -1;
            }
            continue;
        }
        break;
    }while(1);
    if(FD_ISSET(sock, &efds)) return -1; // exception - socket closed
    if(FD_ISSET(sock, &fds))  return  1;
    return 0;
}

это значит так можно проверить и сервер и сокет?
Сергей Борщ
QUOTE (Jenya7 @ Sep 14 2017, 12:35) *
а как теперь проверить жив сокет или нет?
Он закроется, а дальше write() и read() будут возвращать ноль - это и будет признаком того, что соединение разорвано. Кажется так.
Jenya7
Цитата(Сергей Борщ @ Sep 14 2017, 16:07) *
Он закроется, а дальше write() и read() будут возвращать ноль - это и будет признаком того, что соединение разорвано. Кажется так.

допустим сервер не посылает мне ничего но соединение живо. в read() я получу 0 но это может быть потому что сервер ничего не послал.
я думаю есть какие то статусные биты которые говорят что соединение разорвано.
делаю так
Код
#if KEEPALIVE_ON
    /* Set the option active */
    optval = 1;
    optlen = sizeof(optval);
    if(setsockopt(sFd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0)
    {
        close(sFd);
        return (ERROR);
    }
    printf("SO_KEEPALIVE set on socket\n");
    
    /* Interval (in seconds) between keepalives */
    optval = 1;
    setsockopt(sFd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen);
    /* Maximum number of keepalives before dropping the connection */
    optval = 10;
    setsockopt(sFd, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen);
    /* Send first keepalive probe when the connections been idle this time (in seconds) */
    optval = 5;
    setsockopt(sFd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen);
    #endif

теперь по идее мы должны иметь какую то индикацию, статус соединения.
gerber
Если удаленный сервер корректно закрыл TCP-соединение, то на стороне клиента попытка записи-чтения должна возвращать ошибку "Bad file descriptor" или что-то в этом духе. Хотя зависит от реализации стека, вероятно.
Гораздо сложнее история, если разрыв соединения произошел внезапно и физически (выдернули кабель). Тут или мудрить с keep-alive, или самостоятельно реализовывать логику закрытия сокета при неполучении ответа от сервера в то или иное время.
Jenya7
Цитата(gerber @ Sep 14 2017, 19:41) *
Если удаленный сервер корректно закрыл TCP-соединение, то на стороне клиента попытка записи-чтения должна возвращать ошибку "Bad file descriptor" или что-то в этом духе. Хотя зависит от реализации стека, вероятно.
Гораздо сложнее история, если разрыв соединения произошел внезапно и физически (выдернули кабель). Тут или мудрить с keep-alive, или самостоятельно реализовывать логику закрытия сокета при неполучении ответа от сервера в то или иное время.

а код от Эдди
Код
static int waittoread(int sock){
    fd_set fds, efds;
    struct timeval timeout;
    int rc;
    timeout.tv_sec = 1; // wait not more than 1 second
    timeout.tv_usec = 0;
    FD_ZERO(&fds);
    FD_ZERO(&efds);
    FD_SET(sock, &fds);
    FD_SET(sock, &efds);

     rc = select(sock+1, &fds, NULL, &efds, &timeout);
        if(rc < 0)
        {
                putlog("Server not available");
                return -1;
        }
        break;

    if(FD_ISSET(sock, &efds)) return -1; // exception - socket closed
    if(FD_ISSET(sock, &fds))  return  1;
    return 0;
}

разве он не проверяет все случаи? там и сервер и сокет проверяется.
Jenya7
Ну хорошо. Другой вопрос. Я в таске принимаю данные с сервера
Код
mlen = read (soc_desc, read_buff, sizeof(read_buff));

у нас для чтения есть еще три функции
Код
recvfrom( )
recv( )
recvmsg( )

какую лучше использовать? из описания я понял что recvfrom( ), recvmsg( ) - это для UDP, а recv( ) - для TCP.
так ли это или я ошибаюсь?

и потом я не понимаю как синхронизируется посылка-прием между клиентом и сервером. полингом я читаю данные которые давно уже отправлены. нет какого то флага или прерывания от сервера?
Jenya7
Создал сокет как TCP Client. Читаю с сервера, пишу на сервер, все нормально. Но если вытащили кабель или сервер захлопнулся - какие мои действия? Закрыть старый сокет и пытаться открыть новый все время в таске?
Как то не логично. Если связь упала то получается я ломлюсь в закрытую дверь.
Tarbal
Цитата(des333 @ Sep 13 2017, 18:59) *
И какой вывод можно получить?


Что компьютер little endian, а в интернете как водится big endian. Есть такие функции для преобразования
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

https://linux.die.net/man/3/ntohl
Jenya7
Мой девайс присоединен к двум другим. С одним он должен разговаривать по TCP с IP адресом X, с другим по UDP с IP адресом Y.
Физически там только один ETH канал.
Возможно определить два сокета TCP и UDP с разными IP адресами?

Я так понимаю нужно определить на уровне драйвера два IP адреса?
k155la3
Цитата(Jenya7 @ Nov 12 2017, 17:11) *
Мой девайс присоединен к двум другим. С одним он должен разговаривать по TCP с IP адресом X, с другим по UDP с IP адресом Y.
Физически там только один ETH канал.
. . .

Попробуйте на PC
arp -s . . . .
arp -a
Маршрутизатор должен "знать" что на этот один MAC привязаны несколько IP
И естественно Ваш девайс должен уметь с ним (маршрутизатором или другим девайсом) "договориться" об этом автоматически.
ps - из arp /?
Код
Пример:
  > arp -s 157.55.85.212   00-aa-00-62-c6-09  ... Добавляет статическую запись.
  > arp -a                                    ... Выводит ARP-таблицу.
Jenya7
Цитата(k155la3 @ Nov 12 2017, 20:25) *
Попробуйте на PC
arp -s . . . .
arp -a
Маршрутизатор должен "знать" что на этот один MAC привязаны несколько IP
И естественно Ваш девайс должен уметь с ним (маршрутизатором или другим девайсом) "договориться" об этом автоматически.

копаюсь в коде. вижу что определение IP уходит в драйвер лэйер. но в линуксе все драйвера сидят в кернеле. по крайней мере я вижу только объектные файлы.

В камень заходят только TX+/TX-, RX+/RX-. Получается у него внутри и PHY и MAC. Получается все нужно конфигурировать внутри.
k155la3
Надо вместо одного сетевого интерфейса (физического) сделать 2 (виртуальных, с нужным IP).
Для маршрутизаторного ПО (и в Linux ест-но) это должно быть готовое решение.
ps
Для PC/Linux оно должно быть, а вот для embedded - тут вопрос.
psps
Возможно, что такое решение умножит на 2 ресурсы, занимаемые стеком TCP. Влезет ?
IMHO
а тема - IP aliasing sm.gif
Насколько понял, настраивается методом прописки config-файлов Linux sm.gif
Jenya7
Цитата(k155la3 @ Nov 12 2017, 20:53) *
Надо вместо одного сетевого интерфейса (физического) сделать 2 (виртуальных, с нужным IP).
Для маршрутизаторного ПО (и в Linux ест-но) это должно быть готовое решение.
ps
Для PC/Linux оно должно быть, а вот для embedded - тут вопрос.
psps
Возможно, что такое решение умножит на 2 ресурсы, занимаемые стеком TCP. Влезет ?
IMHO
а тема - IP aliasing sm.gif
Насколько понял, настраивается методом прописки config-файлов Linux sm.gif

есть конфигурационные хедеры но там ни слова об IP.

По моему нашел
Цитата
ifAddrAdd( )

NAME

ifAddrAdd( ) - add an interface address for a network interface

SYNOPSIS

STATUS ifAddrAdd
(
char * interfaceName, /* name of interface to configure */
char * interfaceAddress, /* Internet address to assign to interface */
char * broadcastAddress, /* broadcast address to assign to interface */
int subnetMask /* subnetMask */
)

DESCRIPTION

This routine assigns an Internet address to a specified network interface. The Internet address can be a host name or a standard Internet address format (e.g., 90.0.0.4). If a host name is specified, it should already have been added to the host table with hostAdd( ).

You must specify both an interfaceName and an interfaceAddress. A broadcastAddress is optional. If broadcastAddress is NULL, in_ifinit( ) generates a broadcastAddress value based on the interfaceAddress value and the netmask. A subnetMask value is optional. If subnetMask is 0, in_ifinit( ) uses a subnetMask the same as the netmask that is generated by the interfaceAddress. The broadcastAddress is also destAddress in case of IFF_POINTOPOINT.


тут возникает другой вопрос. допустим сконфигурировал
Код
//FIRST IP;
ifAddrSet ("ETH0","10.0.0.10");
ifMaskSet ("ETH0", 0xffffff00);
//SECOND IP
ifAddrAdd ("ETH0","192.168.101.100","192.168.101.255",0xffffff00);

а как задать что первый IP относиться к UDP , а второй IP к TCP?
XVR
Цитата(Jenya7 @ Nov 12 2017, 18:23) *
а как задать что первый IP относиться к UDP , а второй IP к TCP?
Никак, да это и не нужно. Когда вы будете устанавливать соединения с клиентами, то TCP/IP стек сам выберет нужный IP на основании того, куда вы их подключите

Jenya7
Цитата(XVR @ Nov 13 2017, 15:47) *
Никак, да это и не нужно. Когда вы будете устанавливать соединения с клиентами, то TCP/IP стек сам выберет нужный IP на основании того, куда вы их подключите

есть требование чтоб данные сокетов не прерсекались, то есть шли в разных потоках, если можно так выразиться. а если сделать байнд?
Код
struct sockaddr_in localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_addr.s_addr = inet_addr("192.168.1.100");
localaddr.sin_port = 0;  
bind(sockfd, (struct sockaddr *)&localaddr, sizeof(localaddr));
k155la3
Да, мой тезис по alias ошибочен. Два адреса у одного Ethernet-интерфейса будут,
но по приему все будет "сыпать" в одну кучу (на один порт TCP/UDP будут попадать пакеты и для одного
алиасного IP и для другого) .

В Вашем посте выше
Цитата
STATUS ifAddrAdd
(
char * interfaceName, /* name of interface to configure */ <<<<<<<<<<<<<<<<<<<
char * interfaceAddress, /* Internet address to assign to interface */
char * broadcastAddress, /* broadcast address to assign to interface */
int subnetMask /* subnetMask */
)

Если "раздвоить" физ. интерфейс (на ниженем уровне стека или вообще до него)
то задача решается "автоматически".
Как например, если было бы 2 физических Ethernet (интерфейса) и соотв-но 2 привязанных IP. В этом случае при организации
сокета надо указать, а на какой из них (интерфейсов) он будет работать.

Jenya7
Цитата(k155la3 @ Nov 14 2017, 13:24) *
Да, мой тезис по alias ошибочен. Два адреса у одного Ethernet-интерфейса будут,
но по приему все будет "сыпать" в одну кучу (на один порт TCP/UDP будут попадать пакеты и для одного
алиасного IP и для другого) .

В Вашем посте выше

Если "раздвоить" физ. интерфейс (на ниженем уровне стека или вообще до него)
то задача решается "автоматически".
Как например, если было бы 2 физических Ethernet (интерфейса) и соотв-но 2 привязанных IP. В этом случае при организации
сокета надо указать, а на какой из них (интерфейсов) он будет работать.

а мне тут сказали что если делать байнд - два сокета на два разных IP то этого достаточно чтоб разделить потоки на транспортном уровне. даже не знаю, я не большой спец в этих вопросах.
k155la3
Цитата(Jenya7 @ Nov 14 2017, 13:21) *
. . . я не большой спец в этих вопросах.

Да я тоже не спец, скорее соискатель по теме.
Был небольшой опыт по работе с UDP в распределенной интранет.
--------
(0) Канальный уровень, насколько могу предположить, обеспечивается Ethernet фреймами == MAC.
(1) сетевой + транспортный == IP == интерфейс
(2) TCP, UDP, . . . .

между (0) и (1) еще много чего в виде сетевых протоколов нижнего уровня, в том числе ARP, SNMP.

(?) Может знающие подскажут.
bind используется, когда есть несколько открытых сокетов для для передачи, - для указания IP адресов,
на который отсылается пакет ?
(например, порт 80, один сокет для приема, и n сокетов для каждого подключения ? )
Как bind работает при приеме ?



XVR
Цитата
bind используется, когда есть несколько открытых сокетов для для передачи, - для указания IP адресов,
на который отсылается пакет ?
Нет. bind дает вашему локальному сокету адрес. При приеме (когда сокет серверный) именно к этому адресу должны будут присоединяться клиенты (или посылать на него пакеты - например для UDP сокетов). Адрес однозначно определяет в какой сети находится ваш сервер. Система не даст присвоить IP сокету из другой сети.
При передаче все проще - система сама даст адрес сокету, если вы его не присвоили явно через bind. IP будет взято из вашей сети (если сетей несколько, то одно из них - система выберет). Если вы пытаетесь присоединится к адресу не из вашей сети, то пакет будет отправлен в gateway (ну или туда, куда отруководит таблица роутинга).
Если IP назначения принадлежит одной из ваших сетей - пакет будет отправлен напрямую на сервер с локального сокета, который получит адрес в этой самой сети (ну или если он уже имел такой адрес)
k155la3
XVR спасибо за инф.
Jenya7
Цитата(XVR @ Nov 14 2017, 18:11) *
Нет. bind дает вашему локальному сокету адрес. При приеме (когда сокет серверный) именно к этому адресу должны будут присоединяться клиенты (или посылать на него пакеты - например для UDP сокетов). Адрес однозначно определяет в какой сети находится ваш сервер. Система не даст присвоить IP сокету из другой сети.
При передаче все проще - система сама даст адрес сокету, если вы его не присвоили явно через bind. IP будет взято из вашей сети (если сетей несколько, то одно из них - система выберет). Если вы пытаетесь присоединится к адресу не из вашей сети, то пакет будет отправлен в gateway (ну или туда, куда отруководит таблица роутинга).
Если IP назначения принадлежит одной из ваших сетей - пакет будет отправлен напрямую на сервер с локального сокета, который получит адрес в этой самой сети (ну или если он уже имел такой адрес)

у меня IP = 10.0.0.10 а я делаю bind на 192.168.3.10 - поэтому я получаю ошибку на bind?

но в этом идея - развести сокеты по разным IP.
k155la3
Цитата(Jenya7 @ Nov 12 2017, 18:23) *
. . .
тут возникает другой вопрос. допустим сконфигурировал
Код
//FIRST IP;
ifAddrSet ("ETH0","10.0.0.10");           [b]IP для интерфейса, он "видится" маршрутизатором извне[/b]
ifMaskSet ("ETH0", 0xffffff00);             [b]маска. Отсюда видим, что для девайса выделена "минимальная" сеть на 254 (кажется) адреса[/b]
//SECOND IP
ifAddrAdd ("ETH0","192.168.101.100","192.168.101.255",0xffffff00);     [b] (!) А вот тут я не уверен. Диапазон адресов из другой сети [/b]?

. . . .
Отсюда может быть и ошибка.

ps
Может виртуальный интерфейс (второй)
Код
sudo gedit /etc/network/interfaces
И редактируешь его приводя к следующему виду:
auto eth0
iface eth0 inet static
  address 192.168.1.5
  netmask 255.255.255.0
  network 192.168.1.0
  broadcast 192.168.1.255
  gateway 192.168.1.1
  dns-nameservers 8.8.8.8 192.168.1.1

auto eth0:1
iface eth0:1 inet static
  address 192.168.0.5
  netmask 255.255.255.0
  network 192.168.1.0
  broadcast 192.168.1.255
  gateway 192.168.0.1
  hwaddress ether 00269ebba619 --------------------- это похоже на "виртуальный" MAC
  dns-nameservers 8.8.8.8 192.168.1.1
gosha-z
Цитата(XVR @ Nov 14 2017, 15:11) *
Нет. bind дает вашему локальному сокету адрес.
Тогда уж пару адрес-порт, если вы хотите, чтобы при send/sendto у вас source port был определенный. Только для передачи по UDP сокет биндить необязательно, в случае stream протокола "обратка" пойдет по установленному исходящему соединению.
Jenya7
Продолжаю серию дурацких вопросов.
У меня NFS-сервер. Я должен положить в NFS-папку линковочный файл (symbolic link) а NFS клиент открыв его перенаправиться к файлу указанному в symbolic link.
Такое возможно? Или клиент может видеть только свою NFS-папку?
XVR
Цитата
Такое возможно?
Переход по символической ссылке? Возможен конечно.
Цитата
Или клиент может видеть только свою NFS-папку?
Клиент увидит строку с символической ссылкой и перейдет по нет (на клиенте). Куда она будет смотреть - это будет определять клиент. NFS сервер к этому отношения не имеет
Jenya7
Цитата(XVR @ Nov 20 2017, 16:46) *
Переход по символической ссылке? Возможен конечно.
Клиент увидит строку с символической ссылкой и перейдет по нет (на клиенте). Куда она будет смотреть - это будет определять клиент. NFS сервер к этому отношения не имеет

в смысле на клиенте?
я создаю папку на сервере - mkdir("/ram0/NFS_FILES"); а линк указывает на "/ram0/some_file.txt/'' - клиент видит всю файловую систему? я так понимаю у клиента мапиться только эта папка.
XVR
Цитата
я создаю папку на сервере - mkdir("/ram0/NFS_FILES"); а линк указывает на "/ram0/some_file.txt/'' - клиент видит всю файловую систему?
Клиент уыидит файл /ram0/some_file.txt (если такой на клиенте есть), или битую ссылку, если нет. Файл /ram0/some_file.txt с сервера он (клиент) НЕ увидит ни при каком раскладе.
Цитата
я так понимаю у клиента мапиться только эта папка.
Разумеется
Jenya7
Цитата(XVR @ Nov 20 2017, 18:35) *
Клиент уыидит файл /ram0/some_file.txt (если такой на клиенте есть), или битую ссылку, если нет. Файл /ram0/some_file.txt с сервера он (клиент) НЕ увидит ни при каком раскладе.
Разумеется

Я понял. спасибо. эти фантазеры хотят чтоб я слинковал их на файл на сервере.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.