2014-03-06 46 views
0

我遇到了這個tcp服務器的例子,隨Altera Nios II處理器一起提供,我沒有得到關於處理rx_buffer的部分。這個tcp套接字代碼如何處理rx緩衝區?

server.h

typedef struct SSS_SOCKET { 
    enum { 
     READY, COMPLETE, CLOSE 
    } state; 
    int fd; 
    int close; 
    INT8U rx_buffer[SSS_RX_BUF_SIZE]; 
    INT8U *rx_rd_pos; /* position we've read up to */ 
    INT8U *rx_wr_pos; /* position we've written up to */ 
} SSSConn; 

server.c

int data_used = 0, rx_code = 0; 
INT8U *lf_addr; 

conn->rx_rd_pos = conn->rx_buffer; 
conn->rx_wr_pos = conn->rx_buffer; 

printf("[sss_handle_receive] processing RX data\n"); 

while (conn->state != CLOSE) { 
    /* Find the Carriage return which marks the end of the header */ 
    lf_addr = strchr(conn->rx_buffer, '\n'); 

    if (lf_addr) { 
     /* go off and do whatever the user wanted us to do */ 
     sss_exec_command(conn); 
    } 
    /* No newline received? Then ask the socket for data */ 
    else { 
     rx_code = recv(conn->fd, conn->rx_wr_pos, 
       SSS_RX_BUF_SIZE - (conn->rx_wr_pos - conn->rx_buffer) -1, 0); 

     if (rx_code > 0) { 
      conn->rx_wr_pos += rx_code; 

      /* Zero terminate so we can use string functions */ 
      *(conn->rx_wr_pos + 1) = 0; 
     } 
    } 

    /* 
    * When the quit command is received, update our connection state so that 
    * we can exit the while() loop and close the connection 
    */ 
    conn->state = conn->close ? CLOSE : READY; 

    /* Manage buffer */ 
    data_used = conn->rx_rd_pos - conn->rx_buffer; 
    memmove(conn->rx_buffer, conn->rx_rd_pos, 
      conn->rx_wr_pos - conn->rx_rd_pos); 
    conn->rx_rd_pos = conn->rx_buffer; 
    conn->rx_wr_pos -= data_used; 
    memset(conn->rx_wr_pos, 0, data_used); 
} 

具體而言,我看不到data_used變量的目的。 rx_rd_pos指向rx_buffer,並且兩者都沒有出現任何操作,那麼它們將如何不同?實際上,似乎在Manage buffer下發生的唯一情況是將數據複製到rx_buffer。我確信我錯過了一些簡單的東西,但我似乎無法看到它。

感謝您提前提供任何幫助。

編輯:這是sss_exec_command()函數。

void sss_exec_command(SSSConn* conn) { 
int bytes_to_process = conn->rx_wr_pos - conn->rx_rd_pos; 
INT8U tx_buf[SSS_TX_BUF_SIZE]; 
INT8U *tx_wr_pos = tx_buf; 

INT8U error_code; 

/* 
* "SSSCommand" is declared static so that the data will reside 
* in the BSS segment. This is done because a pointer to the data in 
* SSSCommand 
* will be passed via SSSLedCommandQ to the LEDManagementTask. 
* Therefore SSSCommand cannot be placed on the stack of the 
* SSSSimpleSocketServerTask, since the LEDManagementTask does not 
* have access to the stack of the SSSSimpleSocketServerTask. 
*/ 
static INT32U SSSCommand; 

SSSCommand = CMD_LEDS_BIT_0_TOGGLE; 

while (bytes_to_process--) { 
    SSSCommand = toupper(*(conn->rx_rd_pos++)); 

    if (SSSCommand >= ' ' && SSSCommand <= '~') { 
     tx_wr_pos += sprintf(tx_wr_pos, 
       "--> Simple Socket Server Command %c.\n", 
       (char) SSSCommand); 
     if (SSSCommand == CMD_QUIT) { 
      tx_wr_pos += sprintf(tx_wr_pos, 
        "Terminating connection.\n\n\r"); 
      conn->close = 1; 
     } else { 
      error_code = OSQPost(SSSLEDCommandQ, (void *) SSSCommand); 

      alt_SSSErrorHandler(error_code, 0); 
     } 
    } 
} 

send(conn->fd, tx_buf, tx_wr_pos - tx_buf, 0); 

return; 

}下面

答案是正確的。我在命令函數中遺漏了rx_rd上的指針運算:P

回答

2

該部分在緩衝區處理完畢後將其從緩衝區中移除。您發佈的代碼從不使用緩衝區中的數據存儲,但sss_exec_command函數將在收到換行符後。該函數傳遞連接,所以它可以增加讀取位置的大小。

使用數據後,緩衝區管理部分回收空間。留在緩衝區中的數據量是寫入位置和讀取位置之間的差異。這些數據從寫入位置移動到緩衝區的開始位置,然後讀寫指針被更新爲新的位置。讀取位置設置爲緩衝區的開始位置,寫入位置減少data_used,這是緩衝區開始和讀取指針之間的原始差異,即所用數據量。

+0

你說得對。我完全錯過了它。謝謝! – dsell002

1

假設代碼實際工作,然後data_used = conn->rx_rd_pos - conn->rx_buffer暗示rx_rd_pos正在更改;當代碼已經使用寫入緩衝區的數據時(它被寫入rx_wr_pos並從rx_rd_pos消耗),這將被改變。這意味着sss_exec_command(conn)正在調整conn。是這樣嗎?