реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> TCPNet проблема с BSD-сокетами, При подключении к серверу не могу принять данные
stepper88
сообщение Jun 6 2012, 12:13
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138



Здравствуйте!
Недавно решил попробовать сокеты BSD в составе кейловского стека (Keil uVision 4.5). Необходимо сделать SNTP клиент, который смог бы получать из сети время. Написал вот такой текст:
Код
#include "LPC23xx.h"
#include "uart.h"
#include "RTL.h"
#include "main.h"
#include <Net_Config.h>

//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------

//   <h>Time server IP
//   ====================
//
//     <o>IP1: Address byte 1 <0-255>
//     <i> Default: 192
#define IP1            192

//     <o>IP2: Address byte 2 <0-255>
//     <i> Default: 168
#define IP2            168

//     <o>IP3: Address byte 3 <0-255>
//     <i> Default: 0
#define IP3            0

//     <o>IP4: Address byte 4 <0-255>
//     <i> Default: 100
#define IP4            13

//   </h>

//------------- <<< end of configuration section >>> -----------------------

OS_TID poolID, timerID, SNTPID;

int sock;

U64 tcp_stack[800/8];
U64 SNTP_stack[800/8];

#define MCLK 48000000                         /* Master Clock 48 MHz         */
#define TCLK       10                         /* Timer Clock rate 10/s       */
#define TCNT (MCLK/TCLK/4)                    /* Timer Counts                */

BOOL tick;
U32  dhcp_tout;
BOOL LCDupdate;

extern LOCALM localm[];                       /* Local Machine Settings      */
#define MY_IP localm[NETIF_ETH].IpAdr
#define DHCP_TOUT   50                        /* DHCP timeout 5 seconds      */

void tcp_task (void) {
  /* Main Thread of the TcpNet. This task should have */
  /* the lowest priority because it is always READY. */
    UART2_init(115200);
    init_TcpNet();
    timerID=os_tsk_create (timer_task, 0x20);
    //poolID=os_tsk_create_user (tcp_task, 0, &tcp_stack, sizeof(tcp_stack));
    //os_dly_wait(1000);
    SNTPID=os_tsk_create_user (SNTP_task, 0x02, &SNTP_stack, sizeof(SNTP_stack));
  while (1)
    {
    main_TcpNet();
    os_tsk_pass();
  }
}

/*--------------------------- timer_poll ------------------------------------*/

void timer_task (void)
{
  os_itv_set (10);
  while (1)
  {
    /* Timer tick every 100 ms */
    timer_tick ();
    tick = __TRUE;
        os_itv_wait ();
  }
}
void SNTP_task (void)
{
    //static int sock;
    int res;
    int addrlen;
    SOCKADDR_IN time_addr;
    char tx_buf[50];
    char rx_buf[50];
    
    tx_buf[0]=0x23;            //SNTPV4 client
    send_string2("SNTP task started\r\n");
    addrlen = sizeof (time_addr);
    
    while(1)
    {
        sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (sock>0)
        {
            time_addr.sin_port      = htons(123);
            time_addr.sin_family    = PF_INET;
            time_addr.sin_addr.s_b1 = IP1;
            time_addr.sin_addr.s_b2 = IP2;
            time_addr.sin_addr.s_b3 = IP3;
            time_addr.sin_addr.s_b4 = IP4;
            connect (sock, (SOCKADDR *)&time_addr, sizeof (time_addr));
            while(1)
            {    
                res = sendto (sock, (char *)&tx_buf, 48, 0, (SOCKADDR *)&time_addr, addrlen);
                if (res <0)
                {
                    break;
                }
                send_string2("Get-time request sent\r\n");
                res = recv (sock, rx_buf, 48, 0);
                if (res <0)
                {
                    switch (res)
                    {
                        case SCK_EINVALID:     send_string2("socket invalid\r\n"); break;
                        case SCK_ECLOSED: send_string2("remote host closed connection\r\n"); break;
                        case SCK_EWOULDBLOCK:    send_string2("function would be locked\r\n"); break;
                        case SCK_ETIMEOUT:    send_string2("Timeout\r\n"); break;
                        case SCK_ELOCKED:     send_string2("function blocked by RTX\r\n"); break;
                    }
                    break;
                }
                os_dly_wait(300);
            }
            closesocket (sock);
            os_dly_wait(300);
        }
        else
        {
            send_string2("Create socket error!\r\n");
            while(1);
        }
    }
}

int main (void)
{
  os_sys_init_user (tcp_task, 0, &tcp_stack, sizeof(tcp_stack));
}

Отправка сообщения серверу командами send() или sendto() проходит нормально - кадр передается на компьютер и там принимается без проблем.
При приеме функции recv() и recvfrom() вываливаются с ошикбой SCK_EINVALID (-2). Если закомментировать участок отправки данных, все равно получаем ту же ошибку.
Настройки Net_Config.h
Сокеты UDP 2, TCP 1. Включены сокеты BSD: BSD сокетов 1, таймаут 20с (по-умолчанию).
В чем может быть проблема?
Заранее спасибо!
P.S. Обновил до Keil 4.53 (что-то поправили в функции recv()) - не помогло.

Сообщение отредактировал stepper88 - Jun 7 2012, 08:40
Go to the top of the page
 
+Quote Post
stepper88
сообщение Jun 8 2012, 06:46
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138



Почему-то у Keil все примеры с использованием функции recv() серверные. Кто-нибудь использовал эту функцию для клиента? Может быть, я что-то неправильно делаю? В частности, в примерах с recv() присутствует функция bind(). Нужна ли она в моем случае?]
Изменил начало кода клиента
Код
    while(1)
    {
        sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (sock>0)
        {        
            addr.sin_port               = 0;
            addr.sin_family              = PF_INET;
            addr.sin_addr.s_addr         = INADDR_ANY;
            bind (sock, (SOCKADDR *)&addr, sizeof(addr));
            
            time_addr.sin_port      = htons(5001);
            time_addr.sin_family    = PF_INET;
            time_addr.sin_addr.s_b1 = IP1;
            time_addr.sin_addr.s_b2 = IP2;
            time_addr.sin_addr.s_b3 = IP3;
            time_addr.sin_addr.s_b4 = IP4;

            connect (sock, (SOCKADDR *)&time_addr, sizeof (time_addr));

Теперь при приеме появляется ошибка таймаута (сервер пакет отправляет).

Сообщение отредактировал stepper88 - Jun 8 2012, 08:25
Go to the top of the page
 
+Quote Post
Hamster1979
сообщение Jul 10 2012, 10:04
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 26-03-05
Пользователь №: 3 697



У меня RTL нету, но реализовывал SNTP client под LWIP стек. Если по аналогии то должно быть так:
Код
.......
#define SNTP_GET_SYSTEM_TIME(sec, us)     do { (sec) = 0; (us) = 0; } while(0)
struct sntp_msg {
      u8_t           li_vn_mode;
      u8_t           stratum;
      u8_t           poll;
      u8_t           precision;
      u32_t          root_delay;
      32_t          root_dispersion;
      u32_t          reference_identifier;
      u32_t          reference_timestamp[2];
      u32_t          originate_timestamp[2];
      u32_t          receive_timestamp[2];
      u32_t          transmit_timestamp[2];
};
struct sntp_msg  sntpmsg;
int size;


static void sntp_initialize_request(struct sntp_msg *req)
{
          memset(req, 0, SNTP_MSG_LEN);
          req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;

          u32_t sntp_time_sec, sntp_time_us;

          /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */
          SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us);

          sntp_last_timestamp_sent[0] = htonl(sntp_time_sec + DIFF_SEC_1900_1970);
          req->transmit_timestamp[0] = sntp_last_timestamp_sent[0];

          /* we send/save us instead of fraction to be faster... */
          sntp_last_timestamp_sent[1] = htonl(sntp_time_us);

          req->transmit_timestamp[1] = sntp_last_timestamp_sent[1];
  }
}

..............

        sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (sock>0)
        {        
            addr.sin_port               = htons(INADDR_ANY);
            addr.sin_family              = PF_INET;
            addr.sin_addr.s_addr         = htonl(INADDR_ANY);
            if (bind (sock, (SOCKADDR *)&addr, sizeof(addr)) == 0)
           {
                   /* prepare SNTP request */
                   sntp_initialize_request(&sntpmsg);
                   time_addr.sin_port      = htons(123);
                   time_addr.sin_family    = AF_INET;
                   time_addr.sin_addr.s_b1 = IP1;
                   time_addr.sin_addr.s_b2 = IP2;
                   time_addr.sin_addr.s_b3 = IP3;
                   time_addr.sin_addr.s_b4 = IP4;
      
                  /* send SNTP request to server */
                  if(sendto (sock, (char *)&sntpmsg, 48, 0, (SOCKADDR *)&time_addr, addrlen)>=0)
                  {
                           size = recvfrom (sock, rx_buf, sizeof (rx_buf), 0, (SOCKADDR *)&time_addr, &addrlen);

                           /* if the response size is good */
                          if (size == 48)
                          {

                                /* if this is a SNTP response... */
                                if (((sntpmsg.li_vn_mode & 0x07) == 0x04) || ((sntpmsg.li_vn_mode & 0x07) == 0x05))
                                {
                                   /* do time processing */
                                   sntp_process(sntpmsg.receive_timestamp);
                                }
                                else
                                {
                                    send_string2("sntp_request: not response frame code\n");
                                }
                         }
                         else
                         {
                                 send_string2("sntp_request: not sendto==%i\n");
                         }                          
                  }                            
           }

..................


Сообщение отредактировал Hamster1979 - Jul 10 2012, 10:08
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 09:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.01417 секунд с 7
ELECTRONIX ©2004-2016