Thông báo

Collapse
No announcement yet.

Giao thức TCP/IP và Web server với AVR

Collapse
This is a sticky topic.
X
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • nttam79
    replied
    Nguyên văn bởi nacdanh90 Xem bài viết
    Em chào thầy và các anh! Thầy và các anh đã làm qua giao thức TCP cho em hỏi một chút ạ! Em thầy ở gói tin Tcp để khởi tạo kết nối có một trường là Option. trường này theo thầy Tâm sẽ là 8bytes. trong đó có chứa MSS. nhưng em thấy trong wireshark lại là 12byte. trong đó có thêm mấy trường nữa ngoại trường MSS như : NOP, window scale. và em thấy header tcp của gói tin tcp syn là 32 byte chứ ko phải là 28 bytes? thầy và các anh có thể giải thích giúp em tại sao ko a?
    Trường Option trong TCP Header không qui định chiều dài bắt buộc, miễn là phải chẵn 32 bit (nếu không phải chèn thêm Padding vào). Trường data offset sẽ cho ta biết chính xác chiều dài của Header, từ đó ta biết được option dài bao nhiêu. Vì vậy trường Option có thể là 8, 12 byte,... Nội dung chứa trong trường option thì tùy thuộc vào dịch vụ. Tương tự vậy Header TCP của gói syn có thể dài 32 byte (12 byte option).

    Leave a comment:


  • nacdanh90
    replied
    Em chào thầy và các anh! Thầy và các anh đã làm qua giao thức TCP cho em hỏi một chút ạ! Em thầy ở gói tin Tcp để khởi tạo kết nối có một trường là Option. trường này theo thầy Tâm sẽ là 8bytes. trong đó có chứa MSS. nhưng em thấy trong wireshark lại là 12byte. trong đó có thêm mấy trường nữa ngoại trường MSS như : NOP, window scale. và em thấy header tcp của gói tin tcp syn là 32 byte chứ ko phải là 28 bytes? thầy và các anh có thể giải thích giúp em tại sao ko a?

    Leave a comment:


  • BMD2008
    replied
    Anh Tâm ơi cho em hỏi. Phần này anh dùng địa chỉ IP để điều khiển là IP động hay IP tĩnh vậy

    Leave a comment:


  • sotuoi
    replied
    Bạn hàn máy chân port bật tắt led vào board điều khiển động cơ là được chứ gì đâu. vd: Led1 -> trái, Led2 phài, led3 nhanh, led4 chậm

    Leave a comment:


  • tieuthienho
    replied
    Chào thầy Tâm và các bạn!
    Mình có vấn đề muốn hỏi ý kiến mọi người. Đó là sau khi đã điều khiển on/off được thiết bị, em muốn điều khiển thêm động cơ DC (nhanh, chậm, trái, phải) thì nên bắt đầu thế nào?

    Leave a comment:


  • nacdanh90
    replied
    Em chào thầy và các anh! Thầy và các anh đã làm về project này cho em hỏi về đoạn cảnh báo sau:
    ../ip.c:45: warning: pointer targets in passing argument 1 of 'send_string' differ in signedness
    Ý nghĩa của đoạn cảnh báo trên và cách sửa ra sao ạ ?

    Leave a comment:


  • vutrv
    replied
    Hi anh Tâm, đoạn code sau để thiết lập kết nối với sever, không biết nếu sever nằm ở bên ngoài thì mình có cần xác định địc chỉ MAC của nó hay không? hay chỉ cần gửi đúng địa chỉ IP thôi vậy?

    // send SYN packet to initial connection
    tcp_send_packet (
    rxtx_buffer,
    (WORD_BYTES){TCP_port}, // destination port
    (WORD_BYTES){1200}, // source port
    TCP_FLAG_SYN_V, // flag
    1, // (bool)maximum segment size
    1, // (bool)clear sequence ack number
    0, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data
    0, // tcp data length
    (BYTE*)&server_mac, // server mac address
    (BYTE*)&server_ip ); // server ip address
    flag1.bits.syn_is_sent = 1;
    }

    Mong anh hỗ trợ, xin cảm ơn rất nhiều.

    Leave a comment:


  • vutrv
    replied
    Nguyên văn bởi nttam79 Xem bài viết
    Bạn có thể dùng UDP hay TCP để gửi về cho máy tính có IP tĩnh (hay dựa vào domain name).
    Hi gửi như thế nào vậy anh Tâm?
    EM có tham khảo project avrnet (AVR Portal : AVRnet Ethernet development board), nhưng ở đây chỉ dùng trong mạng LAN thôi, còn khi gửi ra ngoài thì chưa được, mong anh debug dùm đoạn code sau:

    //************************************************** ***************************************
    void client_process ( void )
    {
    WORD dlength;
    // you can change rx,tx buffer size in includes.h
    BYTE rxtx_buffer[MAX_RXTX_BUFFER];

    // wait for send temparature flag is set, this flag set by time_base function (menu.c)
    if ( flag1.bits.send_gps == 0 )
    return;
    // AVR busy now and wait untill transfer data to web browser completed.
    if ( flag1.bits.syn_is_received )
    return;
    // AVR sent temparature to web server but not found web server on port 80
    //if ( flag1.bits.not_found_server )
    // return;
    // send SYN to initial connection
    if ( flag1.bits.syn_is_sent == 0 )
    {
    // start arp
    // server ip was not found on network
    if ( arp_who_is ( rxtx_buffer, (BYTE*)&server_mac, (BYTE*)&server_ip ) == 0 ) //nếu bỏ đoạn check này thì có đôi khi nó gửi ra được sever bên ngoài nhưng không phải lúc nào cũng chui ra được,
    {
    flag1.bits.send_gps = 0;
    lcd_gotoxy(14,2);
    lcd_print_p ( PSTR ( "ERR" ) );

    return;


    }


    // send SYN packet to initial connection
    tcp_send_packet (
    rxtx_buffer,
    (WORD_BYTES){TCP_port}, // destination port
    (WORD_BYTES){1200}, // source port
    TCP_FLAG_SYN_V, // flag
    1, // (bool)maximum segment size
    1, // (bool)clear sequence ack number
    0, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data
    0, // tcp data length
    (BYTE*)&server_mac, // server mac address
    (BYTE*)&server_ip ); // server ip address
    flag1.bits.syn_is_sent = 1;
    }


    // get new packet
    dlength = enc28j60_packet_receive( (BYTE*)&rxtx_buffer, MAX_RXTX_BUFFER );

    // no new packet incoming
    if ( dlength == 0 )
    {
    // timeout occured, when SYN has been sent but no response from web server
    // reset send_gps and syn_is_sent flags
    if ( flag1.bits.Timeout )
    {
    flag1.bits.Timeout = 0;
    flag1.bits.send_gps = 0;
    flag1.bits.syn_is_sent = 0;
    lcd_gotoxy(14,2);
    lcd_print_p ( PSTR ( "Err" ) );
    }
    return;
    }

    // check ip packet send to avr or not?
    // accept ip packet only
    if ( ip_packet_is_ip ( (BYTE*)&rxtx_buffer ) == 0 )
    {
    return;
    }

    // check SYNACK flag, after AVR send SYN server response by send SYNACK to AVR
    if ( rxtx_buffer [ TCP_FLAGS_P ] == ( TCP_FLAG_SYN_V | TCP_FLAG_ACK_V ) )
    {
    // send ACK to answer SYNACK

    tcp_send_packet (
    (BYTE*)&rxtx_buffer,
    (WORD_BYTES){TCP_port}, // destination port
    (WORD_BYTES){1200}, // source port
    TCP_FLAG_ACK_V, // flag
    0, // (bool)maximum segment size
    0, // (bool)clear sequence ack number
    1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
    0, // tcp data length
    (BYTE*)&server_mac, // server mac address
    (BYTE*)&server_ip ); // server ip address

    // setup http request to server
    dlength = http_put_request_eng( (BYTE*)&rxtx_buffer );


    // send http request packet
    // send packet with PSHACK
    tcp_send_packet (
    (BYTE*)&rxtx_buffer,
    (WORD_BYTES){TCP_port}, // destination port
    (WORD_BYTES){1200}, // source port
    TCP_FLAG_ACK_V | TCP_FLAG_PSH_V, // flag
    0, // (bool)maximum segment size
    0, // (bool)clear sequence ack number
    0, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
    dlength, // tcp data length
    (BYTE*)&server_mac, // server mac address
    (BYTE*)&server_ip ); // server ip address
    return;
    }
    // after AVR send http request to server, server response by send data with PSHACK to AVR
    // AVR answer by send ACK and FINACK to server
    if ( rxtx_buffer [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_PSH_V) )
    {
    dlength = tcp_get_dlength( (BYTE*)&rxtx_buffer );

    // send ACK to answer PSHACK from server
    tcp_send_packet (
    (BYTE*)&rxtx_buffer,
    (WORD_BYTES){TCP_port}, // destination port
    (WORD_BYTES){1200}, // source port
    TCP_FLAG_ACK_V, // flag
    0, // (bool)maximum segment size
    0, // (bool)clear sequence ack number
    dlength, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
    0, // tcp data length
    (BYTE*)&server_mac, // server mac address
    (BYTE*)&server_ip ); // server ip address

    // send finack to disconnect from web server
    tcp_send_packet (
    (BYTE*)&rxtx_buffer,
    (WORD_BYTES){TCP_port}, // destination port
    (WORD_BYTES){1200}, // source port
    TCP_FLAG_FIN_V|TCP_FLAG_ACK_V, // flag
    0, // (bool)maximum segment size
    0, // (bool)clear sequence ack number
    0, // (bool)calculate new seq and seqack number
    0, // tcp data length
    (BYTE*)&server_mac, // server mac address
    (BYTE*)&server_ip ); // server ip address
    return;
    //menu_flag.bits.send_gps = 0;
    //send_syn = 0;
    }
    // answer FINACK from web server by send ACK to web server
    if ( rxtx_buffer [ TCP_FLAGS_P ] == (TCP_FLAG_FIN_V|TCP_FLAG_ACK_V) )
    {
    // send ACK with seqack = 1
    tcp_send_packet (
    (BYTE*)&rxtx_buffer,
    (WORD_BYTES){TCP_port}, // destination port
    (WORD_BYTES){1200}, // source port
    TCP_FLAG_ACK_V, // flag
    0, // (bool)maximum segment size
    0, // (bool)clear sequence ack number
    1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
    0, // tcp data length
    (BYTE*)&server_mac, // server mac address
    (BYTE*)&server_ip ); // server ip address
    // temparature has been sent
    // and wait for next schedule to send temparature
    flag1.bits.send_gps = 0;
    flag1.bits.syn_is_sent = 0;
    //lcd_clear();
    lcd_gotoxy(14,2);
    USART_trans(OK);
    lcd_print_p ( PSTR ( "OK " ) );

    }
    }

    Leave a comment:


  • nacdanh90
    replied
    Vâng ạ! Thắc mắc của em đã được thầy giải thích hết! Em làm thầy mất cả buổi tối rồi!hì Em cảm ơn thầy rất nhiều!
    Last edited by nacdanh90; 28-03-2012, 01:16.

    Leave a comment:


  • nttam79
    replied
    Đã kiểm tra lại code.
    Trong hình vẽ minh họa tôi gõ nhầm 1 số nên giải thích cho bạn chưa chính xác, giờ xin đính chính lại:
    - Chiều dài phần data max là 1500 bytes, min là 46 bytes (chứ không phải 64, trong hình minh họa gõ nhầm). Đây là theo cấu trúc khung Ethernet II frame (đang dùng phổ biến hiện nay), bạn có thể tham khảo thêm trong tiêu chuẩn IEEE802.3 của IEEE, tại website chính thức của IEEE (http://standards.ieee.org/getieee802...8_section1.pdf).
    - Như vậy khi gửi, dữ liệu sẽ chêm vào cho đủ 46 bytes.
    - Giá trị len mà hàm enc28j60PacketReceive trả về như vậy là chiều dài frame ethernet gồm Destination Address + Source Address + type/Length + Data + CRC sẽ bằng 14 + 46 + 4 = 64 trong trường hợp này.
    - Như vậy bạn gửi giá trị len lên MT là giá trị này chứ không phải giá trị len trong giao thức IP (đã trừ đi phần ethernet header).

    Last edited by nttam79; 28-03-2012, 01:13. Lý do: Thêm ảnh minh họa

    Leave a comment:


  • nacdanh90
    replied
    Vâng! Tại vì em thấy trong hình:
    TCP/IP over Ethernet: Layer 2
    Theo hình trên 64 byte(min) đó là gồm cả Destination Address + Source Address + type/Length+ CRC còn trong hình trên bài của thầy là 64byte min đó nó chỉ là độc phần data nên em thấy hơi mâu thuẫn nhau.

    hi. May quá có thầy giải thích làm em "sáng" ra nhiều vấn đề mà em thắc mắc.
    Tiện đây thầy cho em hỏi nốt một vấn đề này: biến len được trả về từ hàm enc28j60PacketReceive nó có gồm cả chiều dài của 4 byte CRC ko ạ? Theo như thầy hướng dẫn ở đầu thì Enc28j60 nó tự lược bỏ đi phần này. Nhưng trong hình trên thì cộng cả 4 byte CRC vào Ethernet Frame mới có chiều dài là 64byte.
    Last edited by nacdanh90; 28-03-2012, 00:42.

    Leave a comment:


  • nttam79
    replied
    Nguyên văn bởi nacdanh90 Xem bài viết
    Vâng ạ! Em cảm ơn thầy. E quên mất con số 64 đó trong hình vẽ của thầy.hi. Nhưng e xem lại data sheets của enc28j60 đoạn SAMPLE RECEIVE PACKET LAYOUT phần Packetdata nó gồm: Destination Address,Source Address,type/Length, Data. Vậy thì trong hàm enc28j60PacketReceive thầy gán biến len=các bit từ 0..15 của RECEIVE STATUS VECTORS thì đây được coi là chiều dài của riêng phần data(+padding thêm vào cho đủ 64byte nếu data <64byte) chứ không tính chiều dài của các trường Destination Address,Source Address,type/Length ạ?Nếu theo như giải thích bên trên của thầy thì em hiểu như vậy!Ko biết có đúng không ạ?

    Em hỏi về vấn đề này hơi kĩ mong thầy và các anh thông cảm! Em chưa muốn chuyển sang tầng khác trong khi tầng đầu tiên chưa hiểu rõ bản chất!
    Biến len = (Destination Address + Source Address + type/Length + Data) được trả từ hàm enc28j60PacketReceive->ethGetFrame->ethService.
    Trong hàm ethService, biến len được trừ đi phần Ethernet Header (= Destination Address + Source Address + type/Length = 6 + 6 +2 = 14 bytes) và truyền sang hàm IPProcess:
    Code:
    IPProcess( len-ETH_HEADER_LEN, (struct ntIPHeader*)&ethBuffer[ETH_HEADER_LEN] );
    Vậy biến len trong hàm IPProcess và arpArpProcess đã được trừ đi 14 bytes ethernet header (tức là phần Destination Address,Source Address,type/Length).

    Leave a comment:


  • nacdanh90
    replied
    Vâng ạ! Em cảm ơn thầy. E quên mất con số 64 đó trong hình vẽ của thầy.hi. Nhưng e xem lại data sheets của enc28j60 đoạn SAMPLE RECEIVE PACKET LAYOUT phần Packetdata nó gồm: Destination Address,Source Address,type/Length, Data. Vậy thì trong hàm enc28j60PacketReceive thầy gán biến len=các bit từ 0..15 của RECEIVE STATUS VECTORS thì đây được coi là chiều dài của riêng phần data(+padding thêm vào cho đủ 64byte nếu data <64byte) chứ không tính chiều dài của các trường Destination Address,Source Address,type/Length ạ?Nếu theo như giải thích bên trên của thầy thì em hiểu như vậy!Ko biết có đúng không ạ?

    Em hỏi về vấn đề này hơi kĩ mong thầy và các anh thông cảm! Em chưa muốn chuyển sang tầng khác trong khi tầng đầu tiên chưa hiểu rõ bản chất!
    Last edited by nacdanh90; 27-03-2012, 22:53.

    Leave a comment:


  • nttam79
    replied
    Nguyên văn bởi nacdanh90 Xem bài viết
    Thầy và các anh giải thích giúp em vẫn đề này với ạ! Trong bản tin ARP request em bắt được từ wireShark gói tin này có độ dài là 42bytes. và mỗi lần em dùng máy tính ping đến một IP thì em thấy nó gửi 12 gói tin broadcast ARP request.
    Enc28j60 của em nhận được cả 12 paket đó.
    Nhưng khi em gửi byte cao và byte thấp của biến len về máy tính thì gộp lại cả biến len lại có độ dài là 64bytes?
    Trong giao thức Ethernet, chiều dài phần data (payload), được qui định tối đa là 1500 bytes, tối thiểu là 46 bytes, bạn có thể xem lại ở phần đầu, phần giao thức ethernet, hình minh họa cấu trúc khung ethernet (hình này để nhầm là 64). Khi gửi gói IP có kích thước nhỏ hơn 46 byte, cần phải chèn thêm các byte padding cho đủ 46, nhưng thông tin về chiều dài gói IP trong header IP vẫn chính xác. Trong firmware của chúng ta, biến len của giao thức ethernet (trả về bởi hàm enc28j60PacketReceive) được tính là chiều dài phần payload này + ethernet header len + CRC = 46 +14 + 4 = 64. Còn phần mềm wireshark khi bắt gói tin sẽ báo đúng kích thước thật của gói IP. Chính vì vậy xem trên wireshark, bạn sẽ thấy kích thước thực của gói IP là 42 bytes, trong khi đó biến len trong trong hàm ethGetframe là chiều dài của frame ethernet nên nó là 64.
    Last edited by nttam79; 28-03-2012, 01:11.

    Leave a comment:


  • nacdanh90
    replied
    Thầy và các anh giải thích giúp em vẫn đề này với ạ! Trong bản tin ARP request em bắt được từ wireShark gói tin này có độ dài là 42bytes. và mỗi lần em dùng máy tính ping đến một IP thì em thấy nó gửi 12 gói tin broadcast ARP request.
    Enc28j60 của em nhận được cả 12 paket đó.
    Nhưng khi em gửi byte cao và byte thấp của biến len về máy tính thì gộp lại cả biến len lại có độ dài là 64bytes?

    Leave a comment:

Về tác giả

Collapse

nttam79 Tìm hiểu thêm về nttam79

Bài viết mới nhất

Collapse

  • bqviet
    Trả lời cho Đấu tắt điện cho máy tính bảng
    bởi bqviet
    Bqv cáo lỗi vì chưa đủ khả năng diễn giải để người đọc hiểu. Người làm kỹ thuật sâu đôi khi như thế đó. Về việc nạp pin không vào dù cell mới, khả năng cái mạch quản lý đó đã hỏng - cũng chính là nguyên nhân đám cell cũ hỏng từ đầu.
    06-12-2025, 17:17
  • nguyendinhvan
    Trả lời cho Xin hỏi về mạch thu FM/AM trong catsette
    bởi nguyendinhvan
    Theo tôi, nó chỉ là cái Tuy- ê - nơ, hoặc là khối Trung Văn Tần, nó một phần trong cái Da đì ô thôi. Vì có thấy một chỗ có ba chân hàn, giiống như chân Cờ rít sờ tăng 455 ki nô hẹc. Còn khối Tuy ê nơ thì không nhìn thây cái Di ốt Va di cáp...
    05-12-2025, 19:59
  • afrendly
    Trả lời cho Đấu tắt điện cho máy tính bảng
    bởi afrendly
    Có vẻ ngoài hiểu biết của mình rồi. Cuối cùng mình quyết định tìm mua 2 pin trên Shopee, giá 200K thay vào. Tuy nhận pin được 1%, sạc mãi không vào nhưng cũng mở được máy lên. Vậy cũng tạm. Cảm ơn bạn đã hỗ trợ nhé....
    04-12-2025, 01:27
Đang tải...
X