udp_echo.c
来自「在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LE」· C语言 代码 · 共 760 行 · 第 1/2 页
C
760 行
me.sin_addr.s_addr = INADDR_ANY;
me.sin_port = htons(ECHO_PORT);
e = bind(sock, (struct sockaddr*)&me);
if (e != 0)
{
e = t_errno(sock);
ns_printf(pio,"udp_echo: bind error: %d\n", e);
socketclose(sock);
return UDPE_SRV_BIND_FAILED;
}
es_sock = sock;
/* put socket into non-blocking mode */
setsockopt(sock, SOL_SOCKET, SO_NBIO, NULL);
return SUCCESS;
}
/* FUNCTION: udp_cecho_close()
*
* Close the UDP Echo Client for a particular session.
* This function in turn calls udp_client_del().
*
* PARAM1: void * pio
*
* RETURNS: SUCCESS or error number
*/
int
udp_cecho_close(void * pio)
{
UDPCLIENT udpclient;
udpclient=udp_client_from_pio(pio);
if (udpclient == NULL )
{
ns_printf(pio,"echo socket not open\n");
return UDPE_NO_CONN_FOUND;
}
ns_printf(pio,"udp echo - closing client socket\n");
udp_client_del(udpclient);
return SUCCESS;
}
/* FUNCTION: udp_secho_close()
*
* Cleanup the UDP Echo Server
*
* PARAM1: void * pio
*
* RETURNS: SUCCESS or error number
*/
int
udp_secho_close(void * pio)
{
int e=0;
SOCKTYPE sock;
sock = es_sock;
es_sock = INVALID_SOCKET;
if ( sock != INVALID_SOCKET )
{
ns_printf(pio,"udp echo - closing server socket\n");
e = socketclose(sock);
if (e)
{
e = t_errno(sock);
ns_printf(pio,"udp echo: close error %d\n", e);
}
}
if ( e )
return UDPE_SRV_CLOSE_ERR ;
else
return SUCCESS ;
}
/* FUNCTION: udp_sendecho()
*
* Send UDP Echo packets to a remote host. When a UDP Echo Client is
* initialized for a session, rhost field is set to the global
* variable activehost. If this function is called for a different
* rhost, then 1. The previous client connection is closed. 2. A new
* client connection is started for this new rhost.
*
* PARAM1: void * pio
* PARAM2: ip_addr rhost - IP Address of remote host
* PARAM3: int len - Length of packet to be sent
* PARAM4: long times - Number of times packet is to be sent
*
* RETURNS: SUCCESS or error number
*/
int
udp_sendecho(void * pio,
ip_addr rhost, /* already in net endian */
int len, /* length to send */
long times) /* packet length, number of times to send */
{
int e;
UDPCLIENT udpclient;
udpclient=udp_client_from_pio(pio);
if (udpclient == NULL || rhost != udpclient->rhost)
{
if ( udpclient == NULL )
{
ns_printf(pio,"echo socket not open. Opening....\n");
}
else
{
ns_printf(pio,"host changed, restarting client socket \n");
udp_client_del(udpclient);
}
activehost = rhost;
e = udp_cecho_init(pio);
if (e)
return e;
udpclient=udp_client_from_pio(pio);
}
udpclient->replies = 0;
udpclient->times = times;
udpclient->delay = pingdelay;
udpclient->ticks = cticks;
udpclient->state = UDP_BUSY ;
udpclient->len = len ;
udpclient->send_cnt = 0 ;
return udp_send_an_echo(udpclient);
}
/* FUNCTION: udp_send_an_echo()
*
* Send an Echo packet for a UDP Echo Client.
*
* PARAM1: UDPCLIENT udpclient
*
* RETURNS: 0 if SUCCESS or error number
*/
int
udp_send_an_echo(UDPCLIENT udpclient)
{
int e;
if ( udpclient->ticks > cticks )
return UDPE_TIME_NOT_RIPE ;
udpclient->ticks += udpclient->delay; /* Set time for sending next packet*/
ns_printf(udpclient->pio,"sending UDP echo %ld to %s\n",
udpclient->send_cnt,print_ipad(udpclient->rhost));
sprintf_t(echodata + 17, "%-9lu", udpclient->send_cnt );
e = t_send(udpclient->sock, echodata, udpclient->len, 0);
if (e != udpclient->len)
{
e = t_errno(udpclient->sock);
ns_printf(udpclient->pio,"error %d sending UDP echo number %ld\n", e,
udpclient->send_cnt );
ns_printf(udpclient->pio,"UDP Echo Server at %s is possibly shut down\n",
print_ipad(udpclient->rhost));
udp_client_del(udpclient);
return UDPE_ERR_SENDING_ECHO ;
}
udpclient->send_cnt ++;
udpclient->tot_sent ++;
return SUCCESS;
}
/* FUNCTION: udp_echo_poll()
*
* Poll all the UDP Echo related activities. That includes a UDP
* Echo Server and UDP Echo Clients for each I/O session.
*
* PARAM1:
*
* RETURNS: void
*/
static char inbuf[TCP_MSS];
void
udp_echo_poll()
{
struct sockaddr_in him; /* IP info of current rhost */
int len;
int e;
UDPCLIENT tmpclient,nextclient;
in_udpechoq++; /* don't re-entry from tk_yield() */
if (in_udpechoq != 1)
{
in_udpechoq--;
return;
}
/* check for received echo packet */
if (es_sock != INVALID_SOCKET)
{
len = recvfrom(es_sock, inbuf, TCP_MSS, 0, (struct sockaddr *)&him);
if (len < 0)
{
e = t_errno(es_sock);
if (e != EWOULDBLOCK)
dprintf("UDP echo server socket error %d\n", e);
}
else if(len == 0)
{
dtrap("tcp_echo 1\n"); /* socket closed? */
udp_secho_close(NULL);
}
else /* if(len > 0) */
sendto(es_sock, inbuf, len, 0, (struct sockaddr *)&him);
}
for (tmpclient = udpq; tmpclient; tmpclient = nextclient)
{
nextclient=tmpclient->next;
/* check for received echo reply */
len = t_recv(tmpclient->sock, inbuf, TCP_MSS, 0);
if (len < 0)
{
e = t_errno(tmpclient->sock);
if (e != EWOULDBLOCK)
ns_printf(tmpclient->pio,"UDP echo client socket error %d\n", e);
}
else if(len == 0)
{
dtrap("tcp_echo 2\n"); /* socket closed? */
tmpclient->sock=INVALID_SOCKET;
udp_client_del(tmpclient);
continue;
}
else /* if(len > 0) - got some echo data */
{
ns_printf(tmpclient->pio,"UDP echo reply; len:%d, reply:%lu",
len, tmpclient->replies);
tmpclient->replies++;
tmpclient->tot_rcvd++;
/* see if it's one of ours, print number if so */
if (strncmp(inbuf, echodata, 16) == 0)
ns_printf(tmpclient->pio,", Our send#:%ld",atol((&inbuf[17])));
ns_printf(tmpclient->pio,"\n%s",prompt);
}
if ( tmpclient->state == UDP_BUSY )
{
if ( tmpclient->send_cnt >= tmpclient->times )
{
/* Previous "udecho" command has completed */
tmpclient->state = UDP_IDLE ;
}
else
{
if ( udp_send_an_echo(tmpclient) == SUCCESS )
ns_printf(tmpclient->pio,"%s",prompt);
}
}
if ( tmpclient->ticks + (UDP_IDLE_TIMEOUT*TPS) < cticks )
{
/* This client has been lying around ldle for a long time */
ns_printf(tmpclient->pio,"Deleting idle UDP Echo Client.\n%s",prompt);
udp_client_del(tmpclient);
}
}
in_udpechoq--;
}
/* FUNCTION: udp_echo_init()
*
* Do the initialization for UDP Echo - start UDP Echo Server
*
* PARAM1: void
*
* RETURNS: 0 on SUCCESS or error number
*/
int
udp_echo_init(void)
{
return udp_secho_init(NULL);
}
/* FUNCTION: udp_echo_cleanup()
*
* Clean up UDP Echo Server and UDP Echo Clients.
*
* PARAM1: void
*
* RETURNS: 0 on SUCCESS or error number
*/
void
udp_echo_cleanup(void)
{
UDPCLIENT tmpclient=udpq;
UDPCLIENT nextclient;
/* Close the Echo Server sockets */
udp_secho_close(NULL);
/* Do the cleanup for each client connection */
while ( tmpclient )
{
nextclient=tmpclient->next;
udp_client_del(tmpclient);
tmpclient=nextclient;
}
}
/* FUNCTION: udp_echo_stats()
*
* Show statistics about all UDP Echo Clients and Servers
*
* PARAM1: void * pio
*
* RETURNS: 0 on SUCCESS or error number
*/
int
udp_echo_stats(void * pio)
{
ns_printf(pio,"Showing UDP Echo statistics.\n");
if ( es_sock == INVALID_SOCKET )
{
ns_printf(pio," There are no Server connections.\n");
}
else
{
ns_printf(pio," There is one Server connection.\n");
}
if ( udpq == NULL )
ns_printf(pio," There are no Client connections.\n");
else
{
UDPCLIENT tmpclient=udpq;
int cnt=0;
while (tmpclient)
{
cnt++;
ns_printf(pio," Total pkts for Client %d: sent=%ld,rcvd=%ld\n",
cnt,tmpclient->tot_sent,tmpclient->tot_rcvd);
tmpclient=tmpclient->next;
}
ns_printf(pio," Total Client connections=%d.\n",cnt);
}
return SUCCESS;
}
#endif /* UDPSTEST */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?