这是一个TCP服务器的例程,例程是将接收到的数据发送到以太网口
int main(void)
{
/* configure ethernet (GPIOs, clocks, MAC, DMA) */
ETH_BSP_Config();
/* Initilaize the LwIP stack */
LwIP_Init();
/* tcp echo server Init */
tcp_echoserver_init();
/* Infinite loop */
while (1)
{
/* check if any packet received */
if (ETH_CheckFrameR eceived())
{
/* process received ethernet packet */
LwIP_Pkt_Handle();
}
/* handle periodic timers for LwIP */
LwIP_Periodic_Handle(LocalTime);
}
}
/**
* @brief Initializes the tcp echo server
* @param None
* @retval None
*/
void tcp_echoserver_init(void) //初始化SERVER
{
/* create new tcppcb */
tcp_echoserver_pcb = tcp_new();//创建新协议控制块
if (tcp_echoserver_pcb != NULL)
{
err_t err;
/* bind echo_pcb to port 7 (ECHO protocol) */
err = tcp_bind(tcp_echoserver_pcb, IP_ADDR_ANY, 7);//新的协议控制块绑定再端口7上
if (err == ERR_OK)
{
/* start tcp listening for echo_pcb */
tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb); //开始监听
/* initialize LwIPtcp_accept callback function */
tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);//初始化回调函数
}
else
{
printf("Can not bind pcb\n");
}
}
else
{
printf("Can not create new pcb\n");
}
}
/**
* @brief This function is the implementation of tcp_acceptLwIP callback这个函数是实现tcp接受LwIP 回调
* @param arg: not used
* @param newpcb: pointer on tcp_pcbstruct for the newly created tcp connection
* @param err: not used
* @retvalerr_t: error status
*/
static err_ttcp_echoserver_accept(void *arg, structtcp_pcb *newpcb, err_t err)
{
err_tret_err;
structtcp_echoserver_struct *es;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
/* set priority for the newly accepted tcp connection newpcb */
//设置一个新的TCP协议控制块的优先级为1 TCP_PRIO_MIN =1
tcp_setprio(newpcb, TCP_PRIO_MIN);
/* allocate structure es to maintain tcp connection informations */
//为结构体es分配内存
es = (structtcp_echoserver_struct *)mem_malloc(sizeof(structtcp_echoserver_struct));
//内存分配非空
if (es != NULL)
{
es->state = ES_ACCEPTED;
es->pcb = newpcb;
es->p = NULL;
/* pass newly allocated es structure as argument to newpcb */
//将es的参数分配给newpcb
tcp_arg(newpcb, es);
/* initialize lwiptcp_recv callback function for newpcb */
tcp_recv(newpcb, tcp_echoserver_recv);
/* initialize lwiptcp_err callback function for newpcb */
tcp_err(newpcb, tcp_echoserver_error);
/* initialize lwiptcp_poll callback function for newpcb */
tcp_poll(newpcb, tcp_echoserver_poll, 1);
ret_err = ERR_OK;
}
else
{
/* return memory error */
ret_err = ERR_MEM;
}
return ret_err;
}
/**
* @brief This function is the implementation for tcp_recvLwIP callback
* @param arg: pointer on a argument for the tcp_pcb connection
* @param tpcb: pointer on the tcp_pcb connection
* @param pbuf: pointer on the received pbuf
* @param err: error information regarding the reveivedpbuf
* @retvalerr_t: error code
*/
static err_ttcp_echoserver_recv(void *arg, structtcp_pcb *tpcb, structpbuf *p, err_t err) {
structtcp_echoserver_struct *es;
err_tret_err;
LWIP_ASSER T("arg != NULL",arg != NULL);
es = (structtcp_echoserver_struct *)arg;
/* if we receive an empty tcp frame from client => close connection */
if (p == NULL)
{
/* remote host closed connection */
es->state = ES_CLOSING;
if(es->p == NULL)
{
/* we're done sending, close connection */
tcp_echoserver_connection_close(tpcb, es);
}
else
{
/* we're not done yet */
/* acknowledge received packet */
tcp_sent(tpcb, tcp_echoserver_sent);
/* send remaining data*/
tcp_echoserver_send(tpcb, es);
}
ret_err = ERR_OK;
}
/* else : a non empty frame was received from client but for some reason err != ERR_OK */ else if(err != ERR_OK)
{
/* free received pbuf*/
if (p != NULL)
{
es->p = NULL;
pbuf_free(p);
}
ret_err = err;
}
else if(es->state == ES_ACCEPTED)
{
/* first data chunk in p->payload */
es->state = ES_RECEI VED;
/* store reference to incoming pbuf (chain) */
es->p = p;
/* initialize LwIPtcp_sent callback function */
tcp_sent(tpcb, tcp_echoserver_sent);
/* send back the received data (echo) */
tcp_echoserver_send(tpcb, es);
ret_err = ERR_OK;
}
else if (es->state == ES_RECEI VED)
{
/* more data received from client and previous data has been already sent*/ if(es->p == NULL)
{
es->p = p;
/* send back received data */
tcp_echoserver_send(tpcb, es);
}
else
{
structpbuf *ptr;
/* chain pbufs to the end of what we recv'ed previously */
ptr = es->p;
pbuf_chain(ptr,p);
}
ret_err = ERR_OK;
}
/* data received when connection already closed */
else
{
/* Acknowledge data reception */
tcp_recved(tpcb, p->tot_len);
/* free pbuf and do nothing */
es->p = NULL;
pbuf_free(p);
ret_err = ERR_OK;
}
return ret_err;
}