⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp_echo_dh.c

📁 用Dynamic C写的udp程序
💻 C
字号:
/*******************************************************************************
        udp_echo_dh.c
        Z-World, 2002

        A UDP example, that receives packets from any host on UDP port 7, then
        echoes the received packet back to the sender.

        This demonstrates use of a UDP data handler, which is the fastest
        "official" way to implement UDP-based request/response servers.

        This sample will work for Dynamic C 7.30 and later.
*******************************************************************************/
#class auto 			// Change default storage class for local variables: on the stack

/***********************************
 * Configuration                   *
 * -------------                   *
 * All fields in this section must *
 * be altered to match your local  *
 * network settings.               *
 ***********************************/

/*
 * Pick the predefined TCP/IP configuration for this sample.  See
 * LIB\TCPIP\TCP_CONFIG.LIB for instructions on how to set the
 * configuration.  If value >= 100, then use "custom_config.h"
 */
#define TCPCONFIG		1

//#define DCRTCP_VERBOSE
//#define DCRTCP_DEBUG

/*
 * Define the number of socket buffers that will be allocated for
 * UDP sockets.  We only need one UDP socket, so one socket buffer
 * will be enough.
 */
#define MAX_UDP_SOCKET_BUFFERS 1

/*
 * Bump Ethernet MTU up to the max (1500), but only need a few buffers
 */
#define ETH_MTU 1500
#define ETH_MAXBUFS 3

/*
 * UDP demo configuration
 */
#define DISABLE_TCP		// Not using TCP

/*
 *  what local UDP port to use - we receive packets only sent to this port.
 *  Port 7 is the standard echo port.
 */
#define LOCAL_PORT	7


/********************************
 * End of configuration section *
 ********************************/

#memmap xmem
#use "dcrtcp.lib"

udp_Socket sock;

char pktbuf[1500];	// Temp root buffer for packet reassembly

/**
 * 	Handler called from the UDP stack.  If message is relevant, then send
 * 	back a reply.  Return 1 tells UDP stack not to copy this into a
 * 	client buffer; it has already been taken care of-thank you.
 *
 * 	RETURN: 	1 = handler has done all relevant processing for datagram.
 */
int echo_handler(int event, udp_Socket * s, ll_Gather * g,
						_udp_datagram_info * udi)
{
	// Datagram has come in.  It is in the Ethernet receive buffer.  No need to
	// copy it anywhere - we just transmit it straight back to the sender.
	// The relevant information comes in the following fields (not all of which
	// we use here) (see LIB\tcpip\net.lib for structure):
	//  g->data1  ->  IP and UDP headers (root)
	//  g->len1   ->  IP and UDP header length
	//  g->data2  ->  UDP datagram data (xmem) - first buffer
	//  g->len2   ->  UDP datagram data length - first buffer
	//  g->data3  ->  UDP datagram data (xmem) - second buffer **
	//  g->len3   ->  UDP datagram data length - second buffer
	//  udi->remip  -> sender's IP address
	//  udi->remport  ->  sender's UDP port number
	//  udi->flags  -> flags.

   // ** Note: prior to Dynamic C 9.0, only one buffer would be provided (i.e. g->data3 would
   // always be zero).  From DC9.0, it is now possible for the incoming data to be split into
   // two areas.

	// The 'event' parameter determines the type of event.  As of DC 7.30, this is either
	//  UDP_DH_INDATA : incoming datagram
	//  UDP_DH_ICMPMSG : incoming ICMP message.

	if (event == UDP_DH_ICMPMSG) {
		return 1;	// Just ignore incoming ICMP errors.
	}

	// Otherwise, bounce the packet back!  We ignore errors because this
	// is UDP, and the sender will try again.  Not a good idea in general, though.
	// The udp_xsendto() function is new in DC 7.30.  It is the same as udp_sendto()
	// except that the data buffer is in extended memory.  It is slightly more
	// efficient than udp_sendto().

   printf("Got UDP  len1=%2u len2=%4u len3=%4u remip=%08lX remport=%5u len=%u\n",
   	g->len1, g->len2, g->len3, udi->remip, udi->remport, udi->len);

	if (!g->len3)
   	// No second buffer.  This is easy - just use udp_xsendto directly
		udp_xsendto(s, g->data2, g->len2, udi->remip, udi->remport);
   else {
   	// Awkward: got 2 areas, so copy them into a contiguous root buffer and send.
		xmem2root(pktbuf, g->data2, g->len2);
      xmem2root(pktbuf + g->len2, g->data3, g->len3);
		udp_sendto(s, pktbuf, g->len2+g->len3, udi->remip, udi->remport);
   }

	// Return 1 to indicate that all processing has been done.  No copy to
	// normal udp socket receive buffer.
	return 1;
}



void main()
{
	sock_init();

	if(!udp_extopen(&sock, IF_ANY, LOCAL_PORT, -1L, 0, echo_handler, 0, 0)) {
		printf("udp_extopen failed!\n");
		exit(0);
	}

	/* Let the stack do everything... */
	for(;;)
		tcp_tick(NULL);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -