udp_echo.c
来自「在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LE」· C语言 代码 · 共 760 行 · 第 1/2 页
C
760 行
/*
* FILENAME: udp_echo.c
*
* Copyright 1995 - 2000 By InterNiche Technologies Inc. All rights reserved
*
* Test program for UDP sockets API. Implements UDP echo
* server and client DESIGN DESCRIPTION The structure UdpClient is
* used to maintain per-connection information. (connection is a
* misnomer here. Better word can be operation/transaction).
*
* MODULE: MISCLIB
*
* ROUTINES: udp_client_add(), udp_client_del(),
* ROUTINES: udp_client_from_pio(), udp_cecho_init(), udp_secho_init(),
* ROUTINES: udp_cecho_close(), udp_secho_close(), udp_sendecho(),
* ROUTINES: udp_send_an_echo(), udp_echo_poll(), udp_echo_init(),
* ROUTINES: udp_echo_cleanup(), udp_echo_stat
*
* PORTABLE: yes
*/
#include "ipport.h" /* NetPort embedded system includes */
#ifdef UDPSTEST /* whole file can be ifdefed out */
#include "tcpport.h" /* NetPort embedded system includes */
#include "in_utils.h"
/* define NP sockets to standard calls */
#define SOCKTYPE long
#define socket(x,y,z) t_socket(x,y,z)
#define bind(s,a) t_bind(s,a)
#define connect(s,a) t_connect(s,a)
#define sendto(s,b,l,f,a) t_sendto(s,b,l,f,a)
#define recvfrom(s,b,l,f,a) t_recvfrom(s,b,l,f,a)
#define socketclose(s) t_socketclose(s)
#define setsockopt(s, l, o, d) t_setsockopt(s, o, d)
#define ECHO_PORT 7 /* standard UDP/TCP echo port */
#define UDP_IDLE 1
#define UDP_BUSY 2
#define UDP_IDLE_TIMEOUT 600 /* value in seconds */
/* If a UDP Echo client has not been
used for this long, delete it */
SOCKTYPE es_sock = INVALID_SOCKET; /* echo server socket */
extern int kbhit(void);/* from Microsquash|Borland lib*/
extern ip_addr activehost; /* host for ping, echo, etc. */
extern char * prompt;
static char * echodata = "UDP echo number: ";
/* List of error codes used by this file */
#define UDPE_BASE 300
#define UDPE_BAD_SOCKET (UDPE_BASE+1)
#define UDPE_BIND_FAILED (UDPE_BASE+2)
#define UDPE_CONNECT_FAILED (UDPE_BASE+3)
#define UDPE_ALLOC_ERROR (UDPE_BASE+4)
#define UDPE_SRV_BAD_SOCKET (UDPE_BASE+5)
#define UDPE_SRV_BIND_FAILED (UDPE_BASE+6)
#define UDPE_NO_CONN_FOUND (UDPE_BASE+7)
#define UDPE_NODE_NOT_FOUND (UDPE_BASE+8)
#define UDPE_SRV_CLOSE_ERR (UDPE_BASE+9)
#define UDPE_CLIENT_EXISTS (UDPE_BASE+10)
#define UDPE_ERR_SENDING_ECHO (UDPE_BASE+11)
#define UDPE_TIME_NOT_RIPE (UDPE_BASE+12)
#define SUCCESS 0
/* Structure for holding information regarding a UDP Client connection */
struct UdpClient
{
SOCKTYPE sock; /* client socket */
void * pio; /* Output messages go to this device */
ip_addr rhost; /* UDP Echos to be sent to this host */
u_long replies; /* Number of replies received */
u_long times; /* Number of times ECHO is to be sent */
u_long send_cnt ; /* Number of the reply to be sent(counter) */
int state; /* state of the UDP connection */
u_long ticks; /* ClockTick when next EchoPkt is to be sent */
u_long delay; /* Delay between two Echo packets */
int len; /* Lenght of UDP pkt to be sent */
u_long tot_sent; /* Total echo pkts sent */
u_long tot_rcvd; /* Total echo pkts received */
struct UdpClient * next; /* Pointer to the next client connection */
};
typedef struct UdpClient * UDPCLIENT ;
UDPCLIENT udpq; /* Start node for queue of UDP clients */
int udp_client_add(void * pio, SOCKTYPE sock, ip_addr host);
int udp_client_del(UDPCLIENT udpclient);
UDPCLIENT udp_client_from_pio(void * pio);
int udp_cecho_init(void * pio);
int udp_secho_init(void * pio);
int udp_cecho_close(void * pio);
int udp_secho_close (void * pio);
int udp_sendecho(void * pio, ip_addr rhost, int len, long times);
int udp_send_an_echo(UDPCLIENT udpclient);
void udp_echo_poll(void);
int udp_echo_init(void);
void udp_echo_cleanup(void);
int udp_echo_stats(void * pio);
static int in_udpechoq = 0; /* re-entry/queue protection flag */
/* FUNCTION: udp_client_add()
*
* Add a new client to the Queue. Allocates memory for a new node,
* Adds to node to queue, initializes data members
*
* PARAM1: void * pio - GenericIO structure (IN)
* PARAM2: SOCKTYPE sock - Client Socket (IN)
* PARAM3: ip_addr host - Host to whom echo packets are to be sent
*
* RETURNS: SUCCESS or error number
*/
int
udp_client_add(void * pio, SOCKTYPE sock, ip_addr host)
{
UDPCLIENT tmpclient;
in_udpechoq++;
/* Allocate memory */
tmpclient = (UDPCLIENT) npalloc( sizeof(struct UdpClient) ) ;
if ( tmpclient == NULL )
{
ns_printf(pio,"Allocation error.\n");
in_udpechoq--;
return UDPE_ALLOC_ERROR;
}
/* Add the new node to the queue */
if ( udpq == NULL )
{
udpq = tmpclient ;
tmpclient->next=NULL;
}
else
{
/* Insert it at the beginning */
tmpclient->next = udpq;
udpq=tmpclient ;
}
/* Initialize data members */
tmpclient->sock = sock; /* UDP Echo Client's socket */
tmpclient->pio = pio; /* Client's I/O device */
tmpclient->rhost = host; /* UDP Echo Server's IP addr */
tmpclient->times = 1; /* Count of total EchoPkts to be sent */
tmpclient->send_cnt = 0; /* Num of Echo Pkts sent till now */
tmpclient->ticks = cticks; /* Timetick to track sending of echos */
tmpclient->state = UDP_IDLE ; /* Are we sending UDP Echos? No. */
tmpclient->replies = 0 ; /* Num of replies received so far */
tmpclient->len = 64 ; /* Default value of Echo Pkt */
tmpclient->tot_sent = 0;
tmpclient->tot_rcvd = 0;
in_udpechoq--;
return SUCCESS ;
}
/* FUNCTION: udp_client_del()
*
* Purpose : Cleanup stuff for a UDP Echo
* Client Three things to be done here 1. Close the underlying socket
* 2. Remove node from the Q 3. Free the memory used by the node
*
* PARAM1: UDPCLIENT udpclient - Pointer to UDP Echo Client connection
*
* RETURNS: SUCCESS or error number
*/
int
udp_client_del(UDPCLIENT udpclient)
{
int e;
UDPCLIENT tmpclient,prevclient;
in_udpechoq++;
if ( udpclient->sock != INVALID_SOCKET )
{
/* Close the underlying socket */
e = socketclose(udpclient->sock);
if (e)
{
/* socketclose() must have free'd the socket. Hence we
* can't do
* e = t_errno(udpclient->sock);
*/
ns_printf(udpclient->pio,"udp echo: close error %d\n", e);
}
}
/* Remove from the q */
if ( udpq == udpclient )
{
/* It is the first node */
udpq = udpq->next;
}
else
{
prevclient=udpq;
tmpclient=udpq->next;
while ( tmpclient )
{
if ( tmpclient == udpclient )
{
/* Found the node in the list */
prevclient->next=tmpclient->next ;
break;
}
else
{
prevclient=tmpclient;
tmpclient=tmpclient->next ;
}
}
/* Was the node found in Q ? */
if (tmpclient == NULL )
{
/* Node not found in Q !! */
dtrap("udp_echo 0\n");
in_udpechoq--;
return UDPE_NODE_NOT_FOUND ;
}
}
npfree(udpclient);
in_udpechoq--;
return SUCCESS;
}
/* FUNCTION: udp_client_from_pio()
*
* Return the UDP Echo Client connect for a particular session
*
* PARAM1: void * pio
*
* RETURNS: Pointer to UDPCLIENT; or NULL if connection not found
*/
UDPCLIENT
udp_client_from_pio(void * pio)
{
UDPCLIENT tmpclient=udpq;
while ( tmpclient )
{
if ( tmpclient->pio == pio )
break ;
else
tmpclient=tmpclient->next;
}
return tmpclient;
}
/* FUNCTION: udp_cecho_init()
*
* Do the initialization for a
* UDP Echo Client. (for the session identified by pio)
*
* PARAM1: void * pio
*
* RETURNS: SUCCESS or error number
*/
int
udp_cecho_init(void * pio)
{
int e; /* error holder */
struct sockaddr_in me; /* my IP info, for bind() */
struct sockaddr_in him; /* server's IP info, for client connect() */
SOCKTYPE sock;
UDPCLIENT udpclient;
udpclient=udp_client_from_pio(pio);
if (udpclient != NULL )
{
ns_printf(pio,"UDP Echo Client has already been started.\n");
return UDPE_CLIENT_EXISTS ;
}
ns_printf(pio,"udp echo client is starting.\n");
/* open UDP socket */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET)
{
ns_printf(pio,"udp_echo: bad socket: %d\n", sock);
return UDPE_BAD_SOCKET ;
}
me.sin_family = AF_INET;
me.sin_addr.s_addr = INADDR_ANY;
me.sin_port = 0; /* let UDP pick a client 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_BIND_FAILED;
}
/* make client socket a connected socket */
him.sin_family = AF_INET;
if (activehost)
him.sin_addr.s_addr = activehost;
else
him.sin_addr.s_addr = 0x0100007f; /* for testing */
him.sin_port = htons(ECHO_PORT);
e = t_connect(sock, (struct sockaddr *)&him);
if (e != 0)
{
e = t_errno(sock);
ns_printf(pio,"udp_echo: client connect error: %d\n", e);
return UDPE_CONNECT_FAILED;
}
/* put socket into non-blocking mode */
setsockopt(sock, SOL_SOCKET, SO_NBIO, NULL);
udp_client_add(pio,sock,activehost);
return SUCCESS;
}
/* FUNCTION: udp_secho_init()
*
* Initialize the UDP Echo server ( to listen to UDP port 7)
*
* PARAM1: void * pio
*
* RETURNS: SUCCESS or error number
*/
int
udp_secho_init(void * pio)
{
int e; /* error holder */
struct sockaddr_in me; /* my IP info, for bind() */
SOCKTYPE sock;
if ( es_sock != INVALID_SOCKET )
{
ns_printf(pio,"udp echo server is already running.\n" );
return SUCCESS;
}
ns_printf(pio,"udp echo server is starting.\n" );
/* open UDP socket */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET)
{
ns_printf(pio,"udp_echo: bad socket: %d\n", sock);
return UDPE_SRV_BAD_SOCKET;
}
me.sin_family = AF_INET;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?