This chapter describes the main library file,
DCRTCP.LIB, which comprises the configuration macros, the data structures and the functions used to initialize and drive TCP/IP. IP version 4 is supported byDCRTCP.LIB.
NOTE Starting with Dynamic C version 7.05, DCRTCP.LIBis a light wrapper aroundDNS.LIB,IP.LIB,NET.LIB,TCP.LIBandUDP.LIB. No changes are required to existing code.2.1 TCP/IP Configuration
To run the TCP/IP engine, a host (i.e., the controller board) needs to know its IP address, netmask and default gateway. If DNS (Domain Name System) lookups are needed, a host will also need to know the IP address of the local DNS server.
Media Access Control (MAC) address
Some ISPs require that the user provide them with a MAC address for their device. Run the utility program,
/Samples/tcpip/display_mac.c, to display the MAC address of your controller board.2.1.1 IP Addresses Set Manually
The necessary IP addresses can be set at compile time by defining the configuration macros:
MY_IP_ADDRESS,MY_NETMASK,MY_GATEWAYandMY_NAMESERVER. At runtime, the configuration functions,tcp_config(),sethostid()andsethostname()can override the configuration macros.2.1.2 IP Addresses Set Dynamically
The library
BOOTP.LIBallows a target board to be a BOOTP or DHCP client. The protocol used depends on what type of server is installed on the local network. BOOTP and DHCP servers are usually centrally located on a local network and operated by the network administrator. Note that initialization may take longer when using DHCP as opposed to static configuration, but this depends on your server.Both protocols allow a number of configuration parameters to be sent to the client, including:
- client's IP address.
- net mask.
- list of gateways.
- host and default domain names.
- list of name servers.
To use these protocols, include:
#define USE_DHCP
#use DCRTCP.LIBBOOTP assigns permanent IP addresses. DHCP can "lease" an IP address to a host, i.e., assign the IP address for a limited amount of time.
2.1.2.1 BOOTP/DHCP Control Macros
Various macros control the use of DHCP. Apart from setting these macros before '#use dcrtcp.lib', there is typically very little additional work that needs to be done to use DHCP/BOOTP services. Most of the work is done automatically when you call
sock_init()to initialize TCP/IP. There are more control macros available than what are listed here. Please look at the beginning of the file/lib/tcpip/bootp.libfor more information.USE_DHCP
If this macro is defined, the target uses BOOTP and/or DHCP to configure the required parameters. If
USE_DHCPis not defined, thenMY_IP_ADDRESS,MY_NETMASK,MY_GATEWAYand (possibly)MY_NAMESERVERmust be defined in the application program.DHCP_USE_BOOTP
If defined, the target uses the first BOOTP response it gets. If not defined, the target waits for the first DHCP offer and only if none comes in the time specified by
_bootptimeoutdoes it accept a BOOTP response (if any). Use of this macro speeds up the boot process, but at the expense of ignoring DHCP offers if there is an eager BOOTP server on the local subnet.DHCP_CLASS_ID "Rabbit2000-TCPIP:Z-World:Test:1.0.0"
This macro defines a class identifier by which the OEM can identify the type of configuration parameters expected. DHCP servers can use this information to direct the target to the appropriate configuration file. Z-World recommends the standard format: "hardware:vendor:product code:firmware" version.
DHCP_USE_TFTP
If this and
USE_DHCPare defined, the library will use the BOOTP filename and server to obtain an arbitrary configuration file that will be accessible in a buffer at physical address_bootpdata, with length,_bootpsize. The global variables,_bootpdoneand_bootperrorindicate the status of the boot file download.DHCP_USE_TFTPshould be defined to the maximum file size that may be downloaded.DHCP_CLIENT_ID clientid_char_ptr
DHCP_CLIENT_ID_LEN clientid_lengthDefine a client identifier string. Since the client ID can contain binary data, the length of this string must be specified as well. This string MUST be unique amongst all clients in an administrative domain, thus in practice the client ID must be individually set for each client e.g. via front-panel configuration. It is NOT recommended to program a hard-coded string (as for class ID). Note that RFC2132 recommends that the first byte of the string should be zero if the client ID is not actually the hardware type and address of the client (see next).
DHCP_CLIENT_ID_MAC
If defined, this overrides
DHCP_CLIENT_ID, and automatically sets the client ID string to be the hardware type (1 for ethernet) and MAC address, as suggested by RFC2132.2.1.2.2 BOOTP/DHCP Global Variables
The following list of global variables may be accessed by application code to obtain information about DHCP or BOOTP. These variable are only accessible if
USE_DHCPis defined._bootpon
Runtime control of whether to perform DHCP/BOOTP. This is initially set to 'true'. It can be set to false before calling
sock_init(the function that initializes the TCP/IP engine), causing static configuration to be used. Static configuration uses the values defined for the configuration macros,MY_IP_ADDRESSetc. If BOOTP fails during initialization, this will be reset to 0. If reset, then you can calldhcp_acquire()at some later time._survivebootp
Set to one of the following values:
0: If BOOTP/DHCP fails, then a runtime error occurs. This is the default.1: If BOOTP fails, then use the values inMY_IP_ADDRESSetc. If those macros are not defined, a runtime error occurs._dhcphost
IP address of last-used DHCP server (~0UL if none). If
_survivebootpis true, then this variable should be checked to see if DHCP/BOOTP was actually used to obtain the lease. If_dhcphostis ~0UL, then the fallback parameters (MY_IP_ADDRESSetc.) were used since no DHCP server responded._bootphost
IP address of the last-used BOOTP/TFTP server (~0UL if none). Usually obtained from the
siaddrfield of the DHCP OFFER/ACK message. This is the default host used ifNULLis given for the hostname in the call totftp_exec(). This is the host that provides the boot file._dhcplife, _dhcpt1, _dhcpt2
These variables contain various absolute time values (referenced against
SEC_TIMER) at which certain aspects of the DHCP protocol get activated._dhcplifeis when the current lease expires. If_dhcplifeis ~0UL (i.e. 0xFFFFFFFF) then the lease is permanent and the other variables are not used. Otherwise,_dhcpt1is when the current lease must be renewed by the current DHCP server._dhcpt2is when the lease must be re-bound to a possibly different server, if the current server does not respond. In general,_dhcpt1<_dhcpt2<_dhcplife. To work out the number of seconds remaining until the current lease expires, use code similar to:
if (_dhcplife == ~0UL)
printf("Lease is permanent\r\n");
else if (_dhcplife > SEC_TIMER)
printf("Remaining lease %lu seconds\r\n",
_dhcplife - SEC_TIMER);
else
printf("Lease is expired\r\n");_bootptimeout
Number of seconds to wait for a BOOTP or DHCP offer. If there is no response within this time (default 30 sec), then BOOTP is assumed to have failed, and the action specified by
_survivebootpwill be taken. You can set this variable to a different value before callingsock_init()._bootpdone
Is set to a non-zero value when TFTP download of the boot file is complete. This variable only exists if
DHCP_USE_TFTPis defined. It is set to one of the following values:
0: Download not complete, or boot file not yet known.1: Boot file download completed (check_bootperrorfor status).2: No boot file was specified by the server._bootpsize
Indicates how many bytes of the boot file have been downloaded. Only exists if
DHCP_USE_TFTPis defined._bootpdata
Physical starting address of boot data. The length of this area will be
DHCP_USE_TFTPbytes, however, the actual amount of data in the buffer is given by_bootpsize. This variable only exists ifDHCP_USE_TFTPis defined and is only valid if_bootpdoneis 1. You can access the data usingxmem2root()and related functions._bootperror
Indicates any error which occurred in a TFTP process. This variable only exists if
DHCP_USE_TFTPis defined and is only valid when_bootpdoneis 1, in which case_bootperroris set to one of the following values (which are also documented with thetftp_tick()function):2.1.2.3 DHCP Functions
There are two user-callable functions regarding IP address leases. To obtain a lease, call
dhcp_acquire(). To relinquish it, calldhcp_release().2.1.2.4 DHCP Sample Program
The following sample code is a basic TCP/IP program that will initialize the TCP/IP interface, and allow the device to be 'pinged' from another computer on the network. DHCP or BOOTP will be used to obtain IP addresses and other network configuration items. A more extensive sample program is in
Samples\tcpip\dhcp.c. It demonstrates other DHCP features, such as releasing and re-acquiring IP addresses and downloading a configuration file.Program Name: samples/tcpip/dhcp.c
2.1.3 Sizes for TCP/IP I/O Buffers
Starting with Dynamic C version 7.05, TCP and UDP I/O buffers are sized separately using:
TCP_BUF_SIZEdetermines the TCP buffer size and defaults to 4096 bytes.UDP_BUF_SIZEdetermines the UDP buffer size and defaults to 4096 bytes.Compatibility is maintained with earlier versions of Dynamic C. If
SOCK_BUF_SIZEis defined,TCP_BUF_SIZEandUDP_BUF_SIZEwill be assigned the value ofSOCK_BUF_SIZE. IfSOCK_BUF_SIZEis not defined, buttcp_MaxBufSizeis, thenTCP_BUF_SIZEandUDP_BUF_SIZEwill be assigned the value oftcp_MaxBufSize* 2.2.1.3.1 User-supplied Buffers
Starting with Dynamic C version 7.05, a user can associate their own buffer with a TCP or UDP socket. The memory for the buffer must be allocated by the user. This can be done with
xalloc(), which returns a pointer to the buffer. This buffer will be tied to a socket by a call to an extended open function:tcp_extlisten(),tcp_extopen()orudp_extopen(). Each function requires a long pointer to the buffer and its length be passed as parameters.2.2 TCP Socket Interface
Throughout this manual, the term socket refers to four numbers: the IP addresses and port numbers for both sides of a connection.
With Dynamic C version 6.57, each socket must have an associated
tcp_Socketstructure of 145 bytes or audp_Socketstructure of 62 bytes. The I/O buffers are in extended memory. For Dynamic C 7.05 these sizes are 132 bytes and 48 bytes, respectively.For earlier versions of Dynamic C, each socket must have a
tcp_Socketdata structure that holds the socket state and I/O buffers. These structures are, by default, around 4200 bytes each. The majority of this space is used by the input and output buffers.2.2.1 Number of Sockets
Starting with Dynamic C version 7.05, there are two macros that define the number of sockets available:
MAX_TCP_SOCKET_BUFFERSdetermines the maximum number of TCP sockets with preallocated buffers. The default is 4. A buffer is tied to a socket with the first call totcp_open()ortcp_listen().MAX_UDP_SOCKET_BUFFERSdetermines the maximum number of UDP sockets with preallocated buffers. The default is 0. A buffer is tied to a socket with the first call toudp_open().Note that DNS does not need a UDP socket buffer since it manages its own buffer. DHCP and
TFTP.LIB, however, each need one UDP socket buffer.Prior to Dynamic C version 7.05,
MAX_SOCKETSdefined the number of sockets that could be allocated, not including the socket for DNS lookups. If you use libraries such asHTTP.LIBorFTP_SERVER.LIB, you must provide enough sockets inMAX_SOCKETSfor them also.In Dynamic C 7.05 (and later), if
MAX_SOCKETSis defined in an application program,MAX_TCP_SOCKET_BUFFERSwill be assigned the value ofMAX_SOCKETS.2.2.2 Passive Open
There are two ways to open a TCP socket, passive and active. To passively open a socket, call
tcp_listen(); then wait for someone to contact your device. This type of open is commonly used for Internet servers that listen on a well-known port, like 80 for HTTP (Hypertext Transfer Protocol) servers. You supplytcp_listen()with a pointer to atcp_Socketdata structure, the local port number others will be contacting on your device, and the IP address and port number that are valid for the device. If you want to be able to accept connections from any IP address or any port number, set one or both to zero.To handle multiple simultaneous connections, each new connection will require its own
tcp_Socketand a separate call totcp_listen(), but using the same local port number (lportvalue).tcp_listen()will immediately return, and you must poll for the incoming connection. You can manually poll the socket usingsock_established().2.2.3 Active Open
When your Web browser retrieves a page, it actively opens one or more connections to the server's passively opened sockets. To actively open a connection, you call
tcp_open(), which uses parameters that are similar to the ones used intcp_listen(). Supply exact parameters forinaandport, which are the IP address and port number you want to connect to; thelportparameter can be zero, causing an unused local port between 1024 and 65535 to be selected.If
tcp_open()returns zero, no connection was made. This could be due to routing difficulties, such as an inability to resolve the remote computer's hardware address with ARP.2.2.4 Delay a Connection
To accept a connection request when the resources to actually process the request are not available, use the function
tcp_reserveport(). It takes one parameter, the port number where you want to accept connections. When a connection to that port number is requested, the 3-way handshaking is done even if there is not yet a socket available. When replying to the connection request, the window parameter in the TCP header is set to zero, meaning, "I can take no bytes of data at this time." The other side of the connection will wait until the value in the window parameter indicates that data can be sent. Using the companion function,tcp_clearreserve(port number), causes TCP/IP to treat a connection request to the port in the conventional way. The macroUSE_RESERVEDPORTSis defined by default. It allows the use of these two functions.When using
tcp_reserveport, the 2MSL (Maximum Segment Lifetime) waiting period for closing a socket is avoided.2.2.5 TCP Socket Functions
There are many functions that can be applied to an open TCP socket. They fall into three main categories: Control, Status, and I/O.
2.2.5.1 Control Functions for TCP Sockets
These functions change the status of the socket or its I/O buffer.
· sock_abort · sock_flushnext · sock_close · tcp_listen · sock_flush · tcp_open
tcp_open()andtcp_listen()have been explained in previous sections.Call
sock_close()to end a connection. This call may not immediately close the connection because it may take some time to send the request to end the connection and receive the acknowledgements. If you want to be sure that the connection is completely closed before continuing, calltcp_tick()with the socket structure's address. Whentcp_tick()returns zero, then the socket is completely closed. Please note that if there is data left to be read on the socket, the socket will not completely close.Call
sock_abort()to cancel an open connection. This function will cause a TCP reset to be sent to the other end, and all future packets received on this connection will be ignored.For performance reasons, data may not be immediately sent from a socket to its destination. If your application requires the data to be sent immediately, you can call
sock_flush(). This function will try sending any pending data immediately. If you know ahead of time that data needs to be sent immediately, callsock_flushnext()on the socket. This function will cause the next set of data written to the socket to be sent immediately, and is more efficient thansock_flush().2.2.5.2 Status Functions for TCP Sockets
These functions return useful information about the status of either a socket or its I/O buffers.
· sock_bytesready · sock_rbused · sock_dataready · sock_tbleft · sock_established · sock_tbsize · sock_rbleft · sock_tbused · sock_rbsize · tcp_tick
tcp_tick()is the daemon that drives the TCP/IP engine, but it also returns status information. When you supplytcp_tick()with a pointer to atcp_Socket(a structure that identifies a particular socket), it will first process packets and then check the indicated socket for an established connection.tcp_tick()returns zero when the socket is completely closed. You can use this return value after callingsock_close()to determine if the socket is completely closed.
sock_close(&my_socket);
while(tcp_tick(&my_socket)) {
// you can do other things here while waiting for the socket
// to be completely closed.
}These status functions can be used to avoid blocking when using
sock_write()and some of the other I/O functions, as illustrated in the following code.This block of code checks to make sure that there is enough room in the buffer before adding data with a blocking function. .
if(sock_tbleft(&my_socket,size)) {
sock_write(&my_socket,buffer,size);
}This block of code ensures that there is a string terminated with a new line in the buffer, or that the buffer is full before calling
sock_gets():
sock_mode(&my_socket,TCP_MODE_ASCII);
if(sock_bytesready(&my_socket) != -1) {
sock_gets(buffer,MAX_BUFFER);
}2.2.5.3 I/O Functions for TCP Sockets
· sock_fastread · sock_putc · sock_fastwrite · sock_puts · sock_getc · sock_read · sock_gets · sock_write · sock_preread
There are two modes of reading and writing to TCP sockets: ASCII and binary. By default, a socket is opened in binary mode, but you can change the mode with a call to
sock_mode().When a socket is in ASCII mode, it is assumed that the data is an ASCII stream with record boundaries on the newline characters for some of the functions. This behavior means
sock_bytesready()will return ≥0 only when a complete newline-terminated string is in the buffer or the buffer is full. Thesock_puts()function will automatically place a newline character at the end of a string, and thesock_gets()function will strip the newline character.Do not use
sock_gets()in binary mode.2.3 UDP Socket Interface
The UDP protocol is useful when sending messages where either a lost message does not cause a system failure or is handled by the application. Since UDP is a simple protocol and you have control over the retransmissions, you can decide if you can trade low latency for high reliability.
Broadcast Packets
UDP can send broadcast packets (i.e., to send a packet to a number of computers on the same network). This is accomplished by setting the remote IP address to -1, in either a call to
udp_open()or a call toudp_sendto(). When used properly, broadcasts can reduce overall network traffic because information does not have to be duplicated when there are multiple destinations.Checksums
There is an optional checksum field inside the UDP header. This field verifies the header and the data. This feature can be disabled on a reliable network where the application has the ability to detect transmission errors. Disabling the UDP checksum can increase the performance of UDP packets moving through TCP/IP engine. This feature can be modified by:
sock_mode(s, UDP_MODE_CHK); // enable checksums
sock_mode(s, UDP_MODE_NOCHK); // disable checksumsThe first parameter is a pointer to the socket's data structure, either
tcp_Socketorudp_Socket.In Dynamic C version 7.20, some convenient macros offer a safer, faster alternative to using
sock_mode(). They areudp_set_chk(s)andudp_set_nochk(s).Improved Interface
With Dynamic C version 7.05 there is a redesigned UDP API. The new interface is incompatible with the previous one. Section 2.3.1 covers the new interface and Section 2.3.2 covers the previous one.
2.3.1 Dynamic C 7.05 (and later)
This UDP interface is a record service. It receives distinct datagrams and passes them as such to the user program. The socket I/O functions available for TCP sockets will not work for UDP sockets.
See Section 2.3.3 for information on porting a program to the new UDP interface.
2.3.1.1 Control Functions for UDP Sockets
These functions change the status of the socket or its I/O buffer.
· sock_flush · udp_close · sock_flushnext · udp_open
2.3.1.2 I/O Functions for UDP Sockets
These functions handle datagram-at-a-time I/O:
· udp_recv · udp_send · udp_recvfrom · udp_sendto
The write function,
udp_sendto(), allows the remote IP address and port number to be specified. The read function,udp_recvfrom(), identifies the IP address and port number of the host that sent the datagram. There is no longer a UDP read function that blocks until data is ready.2.3.1.3 Status Function for UDP Sockets
These functions return useful information about the status of either a socket or its I/O buffers.
· sock_bytesready · sock_rbused · sock_dataready · sock_tbleft · sock_established · sock_tbsize · sock_rbleft · sock_tbused · sock_rbsize · tcp_tick
For a udp socket,
sock_bytesready()returns the number of bytes in the next datagram in the socket buffer, or -1 if no datagrams are waiting. Note that a return of 0 is valid, since a datagram can have 0 bytes of data.2.3.2 UDP Interface Prior to Dynamic C 7.05
This interface is basically the TCP socket interface with some additional functions for simulating a record service. Some of the TCP socket functions work differently for UDP because of its connectionless state. The descriptions for the applicable functions details these differences.
2.3.2.1 I/O Functions for UDP Sockets
Prior to Dynamic C 7.05, the functions that handle UDP socket I/O are mostly the same functions that handle TCP socket I/O.
· sock_fastread · sock_read · sock_fastwrite · sock_recv · sock_getc · sock_recv_from · sock_gets · sock_recv_init · sock_preread · sock_write · sock_putc · udp_close · sock_puts · udp_open
Notice that there are three additional I/O functions that are only available for use with UDP sockets:
sock_recv(),sock_recv_from()andsock_recv_init(). The status and control functions that are available for TCP sockets also work for UDP sockets, with the exception of the open functions,tcp_listen()andtcp_open().2.3.2.2 Opening and Closing a UDP Socket
udp_open()takes a remote IP address and a remote port number. If they are set to a specific value, all incoming and outgoing packets are filtered on that value (i.e., you talk only to the one remote address).If the remote IP address is set to -1, the UDP socket receives packets from any valid remote address, and outgoing packets are broadcast. If the remote IP address is set to 0, no outgoing packets may be sent until a packet has been received. This first packet completes the socket, filling in the remote IP address and port number with the return address of the incoming packet. Multiple sockets can be opened on the same local port, with the remote address set to 0, to accept multiple incoming connections from separate remote hosts. When you are done communicating on a socket that was started with a 0 IP address, you can close it with
sock_close()and reopen to make it ready for another source.2.3.2.3 Writing to a UDP Socket
Prior to Dynamic C 7.05, the normal socket functions used for writing to a TCP socket will work for a UDP socket, but since UDP is a significantly different service, the result could be different. Each atomic write--
sock_putc(),sock_puts(),sock_write(), orsock_fastwrite()--places its data into a single UDP packet. Since UDP does not guarantee delivery or ordering of packets, the data received may be different either in order or content than the data sent. Packets may also be duplicated if they cross any gateways. A duplicate packet may be received well after the original.2.3.2.4 Reading From a UDP Socket
There are two ways to read UDP packets prior to Dynamic C 7.05. The first method uses the same read functions that are used for TCP:
sock_getc(),sock_gets(),sock_read(), andsock_fastread(). These functions will read the data as it came into the socket, which is not necessarily the data that was written to the socket.The second mode of operation for reading uses the
sock_recv_init(),sock_recv(), andsock_recv_from()functions. Thesock_recv_init()function installs a large buffer area that gets divided into smaller buffers. Whenever a datagram arrives, it is stuffed into one of these new buffers. Thesock_recv()andsock_recv_from()functions scan these buffers. After callingsock_recv_initon the socket, you should not usesock_getc(),sock_read(), orsock_fastread().The
sock_recv()function scans the buffers for any datagrams received by that socket. If there is a datagram, the length is returned and the user buffer is filled, otherwisesock_recv()returns zero.The
sock_recv_from()function works likesock_recv(), but it allows you to record the IP address where the datagram originated. If you want to reply, you can open a new UDP socket with the IP address modified bysock_recv_from().2.3.3 Porting Programs from the older UDP API to the new UDP API
To update applications written with the older-style UDP API, use the mapping information in the following table.
2.4 DNS Lookups
Starting with Dynamic C 7.05, non-blocking DNS lookups are supported. Prior to DC 7.05, there was only the blocking function,
resolve(). Compatibility has been preserved forresolve(),MAX_DOMAIN_LENGTH, andDISABLE_DNS.The application program has to do two things to resolve a host name:
Call
resolve_cancel()to cancel a pending lookup.2.4.1 Configuration Macros for DNS Lookups
DISABLE_DNS
If this macro is defined, DNS lookups will not be done. The DNS subsystem will not be compiled in, saving some code space and memory.
DNS_MAX_RESOLVES
4 by default. This is the maximum number of concurrent DNS queries. It specifies the size of an internal table that is allocated in xmem.
DNS_MAX_NAME
64 by default. Specifies the maximum size in bytes of a host name that can be resolved. This number includes any appended default domain and the
NULL-terminator. Backwards compatibility exists for theMAX_DOMAIN_LENGTHmacro. Its value will be overridden with the valueDNS_MAX_NAMEif it is defined.For temporary storage, a variable of this size must be placed on the stack in DNS processing. Normally, this is not a problem. However, for µC/OS-II with a small stack and a large value for
DNS_MAX_NAME, this could be an issue.DNS_MAX_DATAGRAM_SIZE
512 by default. Specifies the maximum length in bytes of a DNS datagram that can be sent or received. A root data buffer of this size is allocated for DNS support.
DNS_RETRY_TIMEOUT
2000 by default. Specifies the number of milliseconds to wait before retrying a DNS request. If a request to a nameserver times out, then the next nameserver is tried. If that times out, then the next one is tried, in order, until it wraps around to the first nameserver again (or runs out of retries).
DNS_NUMBER_RETRIES
2 by default. Specifies the number of times a request will be retried after an error or a timeout. The first attempt does not constitute a retry. A retry only occurs when a request has timed out, or when a nameserver returns an unintelligible response. That is, if a host name is looked up and the nameserver reports that it does not exist and then the DNS resolver tries the same host name with or without the default domain, that does not constitute a retry.
DNS_MIN_KEEP_COMPLETED
10000 by default. Specifies the number of milliseconds a completed request is guaranteed to be valid for
resolve_name_check(). After this time, the entry in the internal table corresponding to this request can be reused for a subsequent request.DNS_SOCK_BUF_SIZE
1024 by default. Specifies the size in bytes of an xmem buffer for the DNS socket. Note that this means that the DNS socket does not use a buffer from the socket buffer pool.
2.5 Skeleton Program
The following program is a general outline for a Dynamic C TCP/IP program. The first couple of defines set up the default IP configuration information. The "memmap" line causes the program to compile as much code as it can in the extended code window. The "use" line causes the compiler to compile in the Dynamic C TCP/IP code using the configuration data provided above it.
Program Name: /samples/tcpip/icmp/pingme.c
To run this program, start Dynamic C and open the
SAMPLES\TCPIP\ICMP\PINGME.Cfile. Edit theMY_IP_ADDRESS,MY_NETMASK, andMY_GATEWAYmacros to reflect the appropriate values for your device. Run the program and try to runping 10.10.6.101from a command line on a computer on the same physical network, replacing10.10.6.101with your value forMY_IP_ADDRESS.2.5.1 TCP/IP Stack Initialization
The
main()function first initializes the TCP/IP stack with a call tosock_init(). This call initializes internal data structures and enables the Ethernet chip, which will take a couple of seconds with the RealTek chip. At this point, the TCP/IP engine is ready to handle incoming packets.2.5.2 Packet Processing
Incoming packets are processed whenever
tcp_tick()is called. The user-callable functions that calltcp_tick()are:tcp_open,udp_open,sock_read,sock_write,sock_close, andsock_abort. Some of the higher-level protocols, e.g.HTTP.LIB, will calltcp_tick()automatically.It is a good practice to make sure that
tcp_tick()is called periodically in your program to insure that the TCP/IP engine has had a chance to process packets. A rule of thumb is to calltcp_tick()around 10 times per second, although slower or faster call rates should also work. The Ethernet interface chip has a large buffer memory, and TCP/IP is adaptive to the data rates that both end of the connection can handle; thus the system will generally keep working over a wide variety of tick rates.2.5.3 TCP/IP Daemon Computing Time
The computing time consumed by each call to
tcp_tick()varies. Rough numbers are less than a millisecond if there is nothing to do, tens of milliseconds for typical packet processing, and hundreds of milliseconds under exceptional circumstances.2.6 State-Based Program Design
An efficient design strategy is to create a state machine within a function and pass the socket's data structure as a function parameter. This method allows you to handle multiple sockets without the services of a multitasking kernel. This is the way the
HTTP.LIBfunctions are organized. Many of the common Internet protocols fit well into this state machine model.
- Waiting to be initialized
- Waiting for a connection
- Connected states that perform the real work
- Waiting for the socket to be closed
An example of state-based programming is
SAMPLES\TCPIP\STATE.C. This program is a basic Web server that should work with most browsers. It allows a single connection at a time, but can be extended to allow multiple connections.2.6.1 Blocking vs. Non-Blocking
There is a choice between blocking and non-blocking functions when doing socket I/O.
2.6.1.1 Non-Blocking Functions
The
sock_fastread()andsock_preread()functions read all available data in the buffers, and return immediately. Similarly, thesock_fastwrite()function fills the buffers and returns the number of characters that were written. When using these functions, you must ensure that all of the data were written completely.
offset=0;
while(offset<length) {
bytes_written=sock_fastwrite(&socket,buffer+offset,length-offset);
if(bytes_written<0) {
// error handling
}
offset+=bytes_written;
}2.6.1.2 Blocking Functions
The other functions (
sock_getc(),sock_gets(),sock_putc(),sock_puts(),sock_read()andsock_write()) do not return until they have completed or there is an error. If it is important to avoid blocking, you can check the conditions of an operation to insure that it will not block.
sock_mode(socket,TCP_MODE_ASCII);
// ...
if (sock_bytesready(&my_socket) != -1){
sock_gets(buffer,MAX_BUFFER);
}In this case
sock_gets()will not block because it will be called only when there is a complete new line terminated record to read.2.7 Multitasking and TCP/IP
Dynamic C's TCP/IP implementation is compatible with both µC/OS-II and with the language constructs that implement cooperative multitasking: costatements and cofunctions. Note that TCP/IP is not compatible with the slice statement.
2.7.1 µC/OS-II
The TCP/IP engine may be used with the µC/OS-II real-time kernel. The line
#use ucos2.lib#use dcrtcp.libin the application program. Also be sure to call
OSInit()before callingsock_init().Dynamic C version 7.05 and later requires the macro
MAX_SOCKET_LOCKSfor µC/OS-II support. If it is not defined, it will default toMAX_TCP_SOCKET_BUFFERS+TOTAL_UDP_SOCKET_BUFFERS(which isMAX_UDP_SOCKET_BUFFERS+ 1 if there are DNS lookups).If buffers have been
xalloc'd for socket I/O, they should be accounted for inMAX_SOCKET_LOCKS.2.7.2 Cooperative Multitasking
The following program demonstrates the use of multiple TCP sockets with costatements.
Program Name: costate_tcp.c
Program Name: costate_tcp.c (continued)
2.8 Function Reference
This section contains descriptions for all user-callable functions in
DCRTCP.LIB. Starting with Dynamic C 7.05,DCRTCP.LIBis a light wrapper aroundDNS.LIB,IP.LIB,NET.LIB,TCP.LIBandUDP.LIB. This update requires no changes to existing code.Descriptions for select user-callable functions in
ARP.LIB,ICMP.LIB,BSDNAME.LIBandXMEM.LIBare also included here. Note thatARP.LIB,ICMP.LIBandBSDNAME.LIBare automatically#use'd fromDCRTCP.LIB.
arpcache_create
ATHandle arpcache_create(longword ipaddr)Description
Create a new entry in the ARP cache table for the specified IP address. If a matching entry for that address already exists, then that entry is returned. Otherwise, a new entry is initialized and returned. If a new entry is created, then an old entry may need to be purged. If this is not possible, then
ATH_NOENTRIESis returned.Parameter
ipaddr
Return Value
Positive value: success.
ATH_NOENTRIES: no space is available in the table, and none of the entries could be purged because they were all marked as permanent or router entries.Library
arpcache_flush
ATHandle arpcache_flush(ATHandle ath);Description
Mark an ARP cache table entry for flushing. This means that the given table entry will be the first entry to be re-used for a different IP address, if necessary. Any entry (including permanent and router entries) may be flushed except for the broadcast entry.
Parameter
ath
ARP table handle obtained from e.g.
arpcache_search().Return Value
Positive value: success.
ATH_UNUSED: the table entry was unused.ATH_INVALID: theathparameter was not a valid handle.ATH_OBSOLETE: the given handle was valid, but obsoleted by a more recent entry. No change made.Library
arpcache_hwa
ATHandle arpcache_hwa(ATHandle ath, byte * hwa);Description
Copy the ethernet (hardware) address from the given ARP cache table entry into the specified area.
Parameters
ath
hwa
Address of where to store the hardware address (6 bytes).
Return Value
Positive value: handle to the entry.
ATH_UNUSED: the table entry was unused.ATH_INVALID: the ath parameter was not a valid handle.ATH_OBSOLETE: the given handle was valid, but obsoleted by a more recent entry. No change made.Library
arpcache_load
ATHandle arpcache_load(ATHandle ath, byte * hwa, byte iface, word flags, byte router_used);Description
Load an entry in the ARP cache table. The entry must have been created using
arpcache_create(), or be an existing valid entry located viaarpcache_search().This function is primarily intended for internal use by the ARP library, although advanced applications could also use it. Most applications should not need to call this function directly.
Parameters
ath
hwa
Hardware (ethernet) address, or
NULL. PassNULLif the current hardware address is not to be changed.iface
Interface to use (
IF_DEFAULTto use default, or not change current setting).flags
Flags for entry: one or more of the following values, OR'd together:
·ATE_PERMANENT: permanent entry
·ATE_RESOLVING: initiate network resolve for this entry (hwais ignored if this flag is set)
·ATE_RESOLVED: this entry now resolved
·ATE_ROUTER_ENT: this is a router entry
·ATE_FLUSH: mark this entry for flush
·ATE_VOLATILE: set short timeout for this entry
·ATE_ROUTER_HOP: this entry uses the specified router as the first hop.hwaignored.
·ATE_REDIRECTED: this entry redirected by ICMP.
Only one of
ATE_ROUTER_ENTorATE_ROUTER_HOPshould be set. For either of these, the next parameter indicates the router table entry to use.Only one of
ATE_RESOLVINGorATE_RESOLVEDshould be set.router_used
Router table entry. Only used if one of
ATE_ROUTER_ENTorATE_ROUTER_HOPis set in the flags parameter.
Return Value
ATH_NOROUTER: the specified router entry number is invalid. This can be because the router_used parameter is bad, or because the router entry has a mismatching ATH.
ATH_INVALID: invalid table handle passed (or unused entry).
ATH_OBSOLETE: the given handle was valid, but obsoleted by a more recent entry. No change made.Library
arpcache_search
ATHandle arpcache_search(longword ipaddr, int virt);Description
Return handle which refers to the ARP cache table entry for the given IP address. This does not do any resolving. It only consults the existing cache entries. The returned handle is guaranteed to be valid at least until the next call to
tcp_tick(). Usually the handle will be valid for considerably longer, however it is possible for the handle to become obsolete if the cache entry is re-used for a different address. The caller should be able to deal with this possibility. The entry returned for the broadcast address is guaranteed to be permanent.Parameters
ipaddr
IP address to locate in the cache. This may be -1L to locate the broadcast entry or our own IP address to return the "loopback" entry.
virt
0: do not return the broadcast or loopback entries.
1: allow the broadcast or loopback entries.
Positive value: handle to the entry.
ATH_NOTFOUND: no entry exists for the given IP address.Library
_arp_resolve
int _arp_resolve(longword ina, eth_address *ethap, int nowait);Description
Gets the Ethernet address for the given IP address. This function is deprecated starting in Dynamic C 7.20.
Parameters
ina
The IP address to resolve to an Ethernet address.
ethap
The buffer to hold the Ethernet address.
nowait
If 0, return within 750 ms; else if !0 wait up to 5 seconds trying to resolve the address.
Return value
Library
arpresolve_check
ATHandle arpresolve_check(ATHandle ath, longword ipaddr)Description
Check up on status of resolve process initiated by
arpresolve_start(). This function should be called regularly to ensure that an ARP table handle is pointing to the correct entry, and that the entry is still current.This caller must call
tcp_tick()if spinning on this function.Parameters
ath
ARP Table Handle obtained from
arpresolve_start().ipaddr
IP address specified to
arpresolve_start(). If this is zero, no check is performed. Otherwise, the ARP table entry is checked to see that it is the correct entry for the specified IP address.Return Value
Positive value: completed successfully. The return value will be the same as the ath parameter.
ATH_AGAIN: not yet completed, try again later.ATH_FAILED: completed in error. Address cannot be resolved because of a network configuration problem.ATH_TIMEDOUT: resolve timed out. No response from addressee within the configured time limit.ATH_INVALID: theathparameter was not a valid handle|.ATH_OBSOLETE: the given handle was valid, but obsoleted by a more recent entry. Restart usingarpresolve_start().ATH_MISMATCH: theipaddrparameter was not zero, and the IP address does not match the table entry.Library
arpresolve_ipaddr
longword arpresolve_ipaddr(ATHandle ath)Description
Given an ARP table handle, return the IP address of the corresponding table entry.
Parameter
ath
ARP Table Handle obtained from e.g.
router_for().Return Value
0: An error occurred, such as an invalid or obsolete handle.0xFFFFFFFF: The handle refers to either the broadcast address, or to a point-to-point entry whose IP address is not defined.
Else: An IP address. This may be 127.0.0.1 for the loopback entry.Library
arpresolve_start
ATHandle arpresolve_start(longword ipaddr);Description
Start resolve process for the given IP address. This may return immediately if the IP address is in the ARP cache table and still valid. Otherwise, if the IP address is on the local subnet then an ARP resolve request is issued through the appropriate interface. If the address is not on the local subnet, then a router table entry is used and no network activity is necessary (unless the router itself is not resolved, in which case its resolution commences).
Parameter
ipaddr
IP address of host whose hardware address is to be resolved.
Return Value
Positive value: success. The value is actually the ATH of the ARP cache table entry which is (or will be) used. This value should be passed to subsequent calls to
arpresolve_check().
ATH_NOENTRIES: no space is available in the table, and none of the entries could be purged, because they were all marked as permanent or router entries.
ATH_NOROUTER: no router ("gateway") is configured for the specified address, which is not on the local subnet.Library
_chk_ping
longword _chk_ping( longword host_ip, longword *sequence_number);Description
Checks for any outstanding ping replies from host.
_chk_pingshould be called frequently with a host IP address. If an appropriate packet is found from that host IP address, the sequence number is returned through*sequence_number.The time difference between our request and their response is returned in milliseconds.Parameters
host_ip
IP address to receive ping reply from.
sequence_number
Return value
Time in milliseconds from the ping request to the host's ping reply.
If_chk_pingreturns0xffffffffL, there were no ping receipts on this current call.Library
See Also
dhcp_acquire
int dhcp_acquire( void );Description
This function acquires a DHCP lease that has not yet been obtained, or has expired, or was relinquished using
dhcp_release(). Normally, DHCP leases are renewed automatically, however if the DHCP server is down for an extended period then it might not be possible to renew the lease in time, in which case the lease expires and TCP/IP should not be used. When the lease expires,tcp_tick()will return 0, and the global variable for the IP address will be reset to 0. At some later time, this function can be called to try to obtain an IP address.This function blocks until the lease is renewed, or the process times out.
Return value
0: OK, lease was not expired, or an IP address lease was acquired with the same
IP address as previously obtained.
-1: An error occurred, no IP address is available. TCP/IP functionality is thus not
available. Usual causes of an error are timeouts because a DHCP or BOOTP server
is not available within the timeout specified by the global variable
_bootptimeout(default 30 seconds).
1: Lease was re-acquired, however the IP address differs from the one previously
obtained. All existing sockets must be re-opened. Normally, DHCP servers are
careful to reassign the same IP address previously used by the client, however this
is sometimes not possible.Library
dhcp_get_timezone
int dhcp_get_timezone( long * seconds );Description
This function returns the time zone offset provided by the DHCP server, if any, or uses the fallback time zone defined by the
TIMEZONEmacro. Note thatTIMEZONEis expressed in hours, whereas the return result is in seconds.Parameters
seconds
Pointer to result longword. If the return value is 0 (OK), then this will be set to the number of seconds offset from Coordinated Universal Time (UTC). The value will be negative for west; positive for east of Greenwich. If the return value is -1, then the result will be set using the hard-coded value from the macro
TIMEZONE(converted to seconds by multiplying by 3600), or zero if this macro is not defined.
0: Time zone obtained from DHCP.-1: Time zone not valid, or not yet obtained, or not using DHCP.Library
dhcp_release
int dhcp_release( void );Description
This function relinquishes a lease obtained from a DHCP server. This allows the server to re-use the IP address that was allocated to this target. After calling this function, the global variable for the IP address is set to 0, and it is not possible to call any other TCP/IP function which requires a valid IP address. Normally,
dhcp_release()would be used on networks where only a small number of IP addresses are available, but there are a large number of hosts which need sporadic network access.This function is non-blocking since it only sends one packet to the DHCP server and expects no response.
Return value
0: OK, lease was relinquished.
1: Not released, because an address is currently being acquired, or because a boot file
(from the BOOTP or DHCP server) is being downloaded, or because some other
network resource is in use e.g. open TCP socket. Calldhcp_release()again
after the resource is freed.
-1: Not released, because DHCP was not used to obtain a lease, or no lease was acquired.Library
getdomainname
char * getdomainname( char *name, int length );Description
Gets the current domain name. For example, if the controller's internet address is "test.mynetwork.com" then "mynetwork" is the domain portion of the name.
The domain name can be changed by the
setdomainname()function.Parameters
name
length
Maximum length of the name, or zero to get a pointer to the internal domain name string. Do not modify this string!
Return value
If
length≥1: Pointer toname.Iflengthis not long enough to hold the domain name, aNULLstring is written toname.If
length= 0: Pointer to internal string containing the domain name. Do not modify this string!Library
See also
setdomainname, gethostname, sethostname, getpeername, getsockname
Example
main() {
sock_init();
printf("Using %s for a domain\n", getdomainname(NULL, 0));
}
gethostid
longword gethostid( void );Description
Return the IP address of the controller in host format.
Return value
IP address in host format, or zero if not assigned or not valid.
Library
IP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
Example
main() {
char buffer[ 512 ];
sock_init();
printf("My IP address is %s\n", inet_ntoa( buffer, gethostid()));
}
gethostname
char * gethostname( char *name, int length );Description
Gets the host portion of our name. For example if the controller's internet address is "test.mynetwork.com" the host portion of the name would be "test."
The host name can be changed by the
sethostname()function.Parameters
name
length
Maximum length of the name, or zero for the internal host name buffer. Do not modify this buffer.
Return value
length≥1: returnname;length= 0: return internal host name buffer (do not modify!)Library
getpeername
int getpeername( sock_type * s, void * dest, int * len );Description
Gets the peer's IP address and port information for the specified socket.
Parameters
s
dest
Pointer to
sockaddrto hold the socket information for the remote end of the socket. The data structure is:
len
Pointer to the length of
sockaddr. ANULLpointer can be used to represent thesizeof(struct sockaddr).Return value
Library
See also
getsockname
int getsockname( sock_type * s, void * dest, int * len );Description
Gets the controller's IP address and port information for a particular socket.
Parameters
s
dest
Pointer to
sockaddrto hold the socket information for thelocalend of the socket. The data structure is:
len
Pointer to the length of
sockaddr. ANULLpointer can be used to represent thesizeof(struct sockaddr).BSDNAME.LIBwill assume 14 bytes if aNULLpointer is passed.Return value
Library
See also
htonl
longword htonl( longword value );Description
This function converts a host-ordered double word to a network-ordered double word. This function is necessary if you are implementing standard internet protocols because the Rabbit does not use the standard for network-byte ordering. The network orders bytes with the most significant byte first and the least significant byte last. On the Rabbit, the bytes are in the opposite order.
Parameters
value
Return value
Host word in network format, e.g.
htonl(0x44332211)returns 0x11223344.Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
htons
word htons( word value );Description
Converts host-ordered word to a network-ordered word. This function is necessary if you are implementing standard internet protocols because the Rabbit does not use the standard for network-byte ordering. The network orders bytes with the most significant byte first and the least significant byte last. On the Rabbit, the bytes are in the opposite order within each 16-bit section.
Parameters
value
Return value
Host-ordered word in network-ordered format, e.g.
htons(0x1122)returns 0x2211.Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
inet_addr
longword inet_addr( char * dotted_ip_string );Description
Converts an IP address from dotted decimal IP format to its binary representation. No check is made as to the validity of the address.
Parameters
dotted_ip_string
Dotted decimal IP string, e.g. "10.10.6.100".
Return value
0: Failure.
Binary representation ofdotted_ip_string: Success.Library
IP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
inet_ntoa
char *inet_ntoa( char *s, longword ip );Description
Converts a binary IP address to its dotted decimal format, e.g.
inet_ntoa(s,0x0a0a0664)returns a pointer to "10.10.6.100".Parameters
s
Location to place the dotted decimal string. A sufficient buffer size would be 16 bytes.
ip
Return value
Pointer to the dotted decimal string pointed to by
s.Library
IP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
ntohl
longword ntohl( longword value );Description
Converts network-ordered long word to host-ordered long word. This function is necessary if you are implementing standard internet protocols because the Rabbit does not use the standard for network byte ordering. The network orders bytes with the most significant byte first and the least significant byte last. On the Rabbit, the bytes are in the opposite order.
Parameters
value
Return value
Network-ordered long word in host-ordered format,
e.g.ntohl(0x44332211)returns0x11223344Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
ntohs
word ntohs( word value );Description
Converts network-ordered word to host-ordered word. This function is necessary if you are implementing standard internet protocols because the Rabbit does not use the standard for network byte ordering. The network orders bytes with the most significant byte first and the least significant byte last. On the Rabbit, the bytes are in the opposite order.
Parameters
value
Return value
Network-ordered word in host-ordered format,
e.g.ntohs(0x2211)returns 0x1122Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
paddr
unsigned long paddr(void* pointer);Description
Converts a logical pointer into its physical address. Use caution when converting address in the E000-FFFF range. This function will return the address based on the XPC on entry.
Parameters
pointer
Return value
Library
pd_getaddress
void pd_getaddress(int nic, void* buffer);Description
This function copies the Ethernet address (e.g., MAC address) into the buffer.
Parameters
nic
This parameter is reserved for future expandability and for now should be assigned a value of 0.
buffer
Place to copy address to. Must be at least 6 byes.
Return value
Library
Example
main() {
char buf[6];
sock_init();
pd_getaddress(0,buf);printf("Your Link Address is:%02x%02x:%02x%02x:%02x%02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);}
_ping
int _ping( longword host_ip, longword sequence_number );Description
Generates an ICMP request for host. NOTE: this is a macro that calls
_send_ping.Parameters
host_ip
sequence_number
Return value
0: Success.1: Failure: unable to resolve hardware address.-1: Failure: unable to transmit ICMP request.Library
See also
psocket
void psocket( void * s );Description
Given an open UDP or TCP socket, the IP address of the remote host is printed out to the Stdio window in dotted IP format followed by a colon and the decimal port number on that machine. This routine can be useful for debugging your programs.
Parameters
s
Return value
Library
resolve
longword resolve( char *host_string );Description
Converts a text string, which contains either the dotted IP address or host name, into the longword containing the IP address. In the case of dotted IP, no validity check is made for the address. NOTE: this function blocks. Names are currently limited to 64 characters. If it is necessary to lookup larger names include the following line in the application program:
#define DNS_MAX_NAME <len in chars>.If
DISABLE_DNShas been defined,resolve()will not do DNS lookup.If you are trying to resolve a host name, you must set up at least one name server. You can set the default name server by defining the
MY_NAMESERVERmacro at the top of your program. When you callresolve(), it will contact the name server and request the IP address. If there is an error,resolve()will return 0L.To simply convert dotted IP to longword, see
inet_addr().For a sample program, see the Example Using tcp_open() listed under
tcp_open().Parameters
host_string
Pointer to text string to convert.
Return value
0: Failure.!0: The IP address*host_stringresolves to.Library
DNS.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
_arp_resolve, inet_addr, inet_ntoa
resolve_cancel
int resolve_cancel(int handle);Description
Cancels the resolve request represented by the given handle. If the handle is 0, then this function cancels all outstanding resolve requests.
Parameters
handle
Handle that represents a DNS lookup process, or 0 to cancel all outstanding resolve requests.
Return value
RESOLVE_SUCCESS: The resolve request corresponding to the given handle has been cancelled. The given handle will no longer be valid after this value is returned.
RESOLVE_HANDLENOTVALID: There is no request for the given handle.
RESOLVE_NONAMESERVER: No nameserver has been defined.Library
See also
resolve_name_start, resolve_name_check, resolve
resolve_name_check
int resolve_name_check(int handle, longword* resolved_ip);Description
Checks if the DNS lookup represented by the given handle has completed. On success, it fills in the resolved IP address in the space pointed to by
resolved_ip.Parameters
handle
Handle that represents a DNS lookup process.
resolved_ip
A pointer to a user-supplied
longwordwhere the resolved IP address will be placed.Return value
RESOLVE_SUCCESS: The address was successfully resolved. The given handle will no longer be valid after this value is returned.
RESOLVE_AGAINThe resolve process has not completed, call this function again.
RESOLVE_FAILEDThe DNS server responded that the given host name does not exist. The given handle will no longer be valid ifRESOLVE_FAILEDis returned.
RESOLVE_TIMEDOUTThe request has been cancelled because a response from the DNS server was not received before the last timeout expired. The given handle will no longer be valid after this value is returned.
RESOLVE_HANDLENOTVALIDThere is no DNS lookup occurring for the given handle.
RESOLVE_NONAMESERVER: No nameserver has been defined.Library
See also
resolve_name_start, resolve_cancel, resolve
resolve_name_start
int resolve_name_start(char* hostname);Description
Starts the process of resolving a host name into an IP address. The given host name is limited to
DNS_MAX_NAMEcharacters, which is 64 by default (63 characters + theNULLterminator). If a default domain is to be added, then the two strings together are limited toDNS_MAX_NAME.If
hostnamedoes not contain a '.' then the default domain (MY_DOMAIN) , if provided, is appended tohostname. Ifhostnamewith the appended default domain does not exist,hostnameis tried by itself. If that also fails, the lookup fails.If
hostnamedoes contain a '.' thenhostnameis looked up by itself. If it does not exist, the default domain is appended, and that combination is tried. If that also fails, the lookup fails.If
hostnameends with a '.', then the default domain is not appended. The host name is considered "fully qualified." The lookup is attempted without the ending '.' and if that fails no other combinations are attempted.This function returns a handle that must be used in the subsequent
resolve_name_check()andresolve_cancel()functions.Parameters
hostname
Host name to convert to an IP address
Return value
>
0: Handle for calls toresolve_name_check()andresolve_cancel().RESOLVE_NOENTRIES: Could not start the resolve process because there were no resolve entries free.
RESOLVE_LONGHOSTNAME: The given hostname was too large.RESOLVE_NONAMESERVER: No nameserver has been defined.Library
See also
resolve_name_check, resolve_cancel, resolve
rip
char * rip( char * string );Description
Strips newline (\n) and/or carriage return (\r) from a string. Only the first \n and \r characters are replaced with \0s. The resulting string beyond the first \0 character is undefined.
Parameters
string
Return value
Pointer to the modified string.
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
Example
setmode( s, TCP_MODE_ASCII );
...
sock_puts( s, rip( questionable_string ));
NOTE In ASCII mode sock_puts()adds \n;ripis used to make certain the string does not already have a newline character. Remember,ripmodifies the source string, not a copy!
router_add
ATHandle router_add(longword ipaddr, byte iface, longword subnet, longword mask, word flags);Description
Add a router to the router table. The same router can be added multiple times, with different subnet and mask. Normally, only one entry is needed in order to access non-local subnets: this entry should be specified with a zero mask. The hardware address of the router is not immediately resolved, however this can be done explicitly by calling
arpresolve_start()with the same IP address. Otherwise, the router will be resolved only when it first becomes necessary.Parameters
ipaddr
IP address of the router. This address should be on the local subnet, since non-local routers are not supported.
iface
Interface to use to access this router, or
IF_DEFAULT.subnet
Subnet accessible through this entry.
mask
flags
Flags word: set to zero (non-zero reserved for internal use).
Return Value
Positive value: completed successfully. The return value is the ARP cache table entry for this router.
ATH_NOENTRIES: insufficient space in either the router or ARP cache tables.Library
router_del_all
void router_del_all(void);Description
Delete all router table entries. This will make any host that is not on the local subnet inaccessible. This function is usually called in preparation for adding a new router entry.
Library
router_delete
ATHandle router_delete(longword ipaddr);Description
Delete a router from the router table. All instances of the router's IP address are deleted, and the ARP cache table entry is flushed.
Parameter
ipaddr
IP address of the router. This address should be on the local subnet, since non-local routers are not supported.
Return Value
Positive value: completed successfully.
ATH_NOTFOUND: specified entry did not exist.Library
router_for
ATHandle router_for(longword ipaddr, byte * router_used, byte * r_iface);Description
Return the ARP cache table entry corresponding to the router that handles the given IP address. If there is a pre configured router for the given address, it is selected. Otherwise, routers discovered via DHCP or ICMP router discovery are searched, with the highest preference being selected. Failing this, if there is a point-to-point interface, this is selected as the default.
An alternative mode of calling this function is invoked if
ipaddris zero. In this case, the default router for the specified interface (*r_iface) is returned. Ifr_ifaceisNULL, then the default interface is assumed:IF_DEFAULT, the only interface supported at present.IF_DEFAULTmay refer to the primary ethernet NIC or a PPP connection that uses a serial port or the primary ethernet NIC.Parameters
ipaddr
IP address of the host which is not on the local subnet.
router_used
If not
NULL, the byte at this location is set to the index of the router in the router table.r_iface
If not
NULL, the byte at this location is set to the interface number that can access the router.Return Value
Positive value: completed successfully.
ATH_NOROUTER: no suitable router found. Either no router is configured, or the given IP address is on the local subnet.Library
router_print
int router_print(byte r)Description
Print a router table entry, indexed by '
r.' This is for debugging only, since the results are printed to the Dynamic C stdio window. 'r' may be obtained from therouter_for()function, by passing&ras therouter_usedparameter to that function.If the specified router entry is not in use, nothing is printed and the return value is non-zero. Otherwise, the information is printed and zero returned.
See
router_printall()for a description of the output fields printed.Parameter
r
Router table index. A number from 0 through (
ARP_ROUTER_TABLE_SIZE-1).Return Value
0: Success, information printed to stdio window.!0: Entry is not in use.Library
See Also
router_printall
int router_printall(void)Description
Print all router table entries. This is for debugging only, since the results are printed to the Dynamic C stdio window. If no routers exist in the table, nothing is printed and the return value is non-zero.
There are 6 fields for each router entry:
Return Value
0: Success, information printed to stdio window.!0: No routers in the table.Library
_send_ping
int _send_ping( longword host, longword countnum, byte ttl, byte tos, longword *theid );Description
Generates an ICMP request for host.
Parameters
host
countnum
ttl
Time to live for the packets (hop count). 255 is a standard value for this field. See
sock_set_ttl()for details.tos
Type of service on the packets. See
sock_set_tos()for details.theid
The identifier that was sent out.
Return value
0: Success.1: Failure: unable to resolve hardware address.-1: Failure: unable to transmit ICMP request.Library
See also
_chk_ping, _ping, sock_set_ttl, sock_set_tos
setdomainname
char *setdomainname( char *name );Description
The domain name returned by
getdomainname()and used forresolve()is set to the value in the string pointed to byname. Changing the contents of the string after asetdomainname()will change the value of the system domain string. It is not recommended. Instead dedicate a static location for holding the domain name.
setdomainname( NULL )is an acceptable way to remove any domain name and subsequentresolvecalls will not attempt to append a domain name.Parameters
name
Return value
Pointer to string that was passed in.
Library
See also
getdomainname, sethostname, gethostname, getpeername, getsockname
sethostid
longword sethostid( longword ip );Description
This function changes the system's current IP address. Changing this address will disrupt existing TCP or UDP sessions. You should close all sockets before calling this function.
Normally there is no need to call this function. The macro
MY_IP_ADDRESSdefines an initial IP address for this host, or you can defineUSE_DHCPto obtain a dynamically assigned address. In either case, it is not recommended to use this function to change the address.Parameters
ip
Return value
Library
IP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sethostname
char * sethostname( char *name);Description
Sets the host portion of our name.
Parameters
name
Return value
Pointer to internal hostname buffer on success, or
NULLon error (if hostname is too long).Library
sock_abort
void sock_abort( void * s );Description
Close a connection immediately. Under TCP this is done by sending a RST (reset).
Under UDP there is no difference between
sock_close()andsock_abort().Parameters
s
Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_bytesready
int sock_bytesready( void * s );Description
If the socket is in binary mode,
sock_bytesready()returns the number of bytes waiting to be read. If there are no bytes waiting, it returns -1.In ASCII mode,
sock_bytesready()returns -1 if there are no bytes waiting to be read or the line that is waiting is incomplete (no line terminating character has been read). The number of bytes waiting to be read will be returned given one of the following conditions:
In ASCII mode, a blank line will be read as a complete line with length 0, which will be the value returned.
sock_bytesready()handles ASCII mode sockets better thansock_dataready(), since it can distinguish between an empty line on the socket and an empty buffer.Returns the number of bytes in the next datagram to be read. If it is a datagram with no data (an empty datagram), then it will return 0. If there are no datagrams waiting, then it returns -1.
Parameters
s
Return value
-1: No bytes waiting to be read.0: If in ASCII mode and a blank line is waiting to be read;
for DC 7.05 and later, a UDP datagram with 0 bytes of data is waiting to be read.>0: The number of bytes waiting to be read.Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_close
void sock_close( void * s );Description
Attempts to close a socket; no more data may be sent or received through that socket.
In the case of UDP, the socket is closed immediately since UDP is a connectionless protocol. TCP, however, is a connection-oriented protocol so the close must be negotiated with the remote computer. Wait for
tcp_tick()to return zero when passed the socket to ensure that a TCP connection is closed.In emergency cases, it is possible to abort the TCP connection rather than close it. Although not recommended for normal transactions, this service is available and is used by all TCP/IP systems.
Parameters
s
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_dataready
int sock_dataready( void *s );Description
Returns the number of bytes waiting to be read. If the socket is in ASCII mode, this function returns zero if a newline character has not been read or the buffer is not full. For UDP sockets, the function returns the number of bytes in the next datagram.
This function cannot tell the difference between no bytes to read and either a blank line or a UDP datagram with no data. For this reason, use
sock_bytesready()instead.Parameters
s
Return value
0: No bytes to read;
or newline not yet read if the socket is in ASCII mode;
or (for DC 7.05 and later) if a UDP datagram has 0 bytes of data waiting to be read.>0: Number of bytes ready to read.Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See Also
sockerr
char *sockerr( void * s );Description
Gets the last ASCII error message recorded for the specified socket. Use of this function will introduce a lot of string constants in root memory. For production programs, it is better to use error numbers (without translation to strings).
Parameters
s
Return value
Pointer to the string that represents the last error message for the socket.
NULLpointer if there have been no errors.If the symbol
SOCKERR_NO_RETURN_NULLis defined, then if no error occurred the string "OK" will be returned instead of aNULLpointer.The error messages are read-only; do not modify them!
Library
See Also
Example
char *p;
...
if ( p = sockerr( s ))
printf("Socket closed with error '%s'\n\r", p );
sock_error
int sock_error(void *s, int clear);Description
Return the most recent error number for the specified socket, which may be a TCP or UDP socket. Up to two error codes may be queued to a socket.
Parameters
s
clear
0: do not clear the returned error condition.
1: clear the returned error from the socket. You can call this function again to get the next older error code (if any).
Return Value
0: no error.!0: one of theNETERR_*constants defined inNETERRNO.LIB.Library
See Also
sock_established
int sock_established( void *s );Description
TCP connections require a handshaked open to ensure that both sides recognize a connection. Whether the connection was initiated with
tcp_open()ortcp_listen(),sock_established()will continue to return 0 until the connection is established, at which time it will return 1. It is not enough to spin on this after a listen because it is possible for the socket to be opened, written to and closed between two checks.sock_bytesready()can be called withsock_established()to handle this case.UDP is a connectionless protocol, hence
sock_established()always returns 1 for UDP sockets.Parameters
s
Return value
0: Not established.1: Established.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_fastread
int sock_fastread( tcp_Socket *s, byte *dp, int len );Description
sock_fastread()attempts to read data from a socket. If possible, the buffer,dp, is filled, otherwise, only the number of bytes read is returned. A return value of -1 indicates a socket error.This function cannot be used on UDP sockets after
sock_recv_init()is called.Parameters
s
dp
Buffer to put bytes that are read.
len
Maximum number of bytes to write to the buffer.
Return value
≥
0: Success, number of bytes read.-1: Error.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_read, sock_fastwrite, sock_write
Example
Note that
sock_fastread()andsock_read()do not necessarily return a complete or single line--they return blocks of bytes. In comparison,sock_getc()returns a single byte at a time and thus yields poor performance.
do {
/* this function does not block */
len = sock_fastread( s, buffer, sizeof(buffer)-1 );
if (len>0) {
buffer[ len ] = 0;
printf( "%s", buffer );
}
} while(tcp_tick(s));
sock_fastwrite
int sock_fastwrite( tcp_Socket *s, byte *dp, int len );Description
Writes up to
lenbytes fromdpon sockets. This function writes as many bytes as possible to the socket and returns that number of bytes.For UDP,
sock_fastwrite()will send one record iflen <= ETH_MTU - 20 - 8
ETH_MTUis the Ethernet Maximum Transmission Unit; 20 is the IP header size and 8 is the UDP header size. By default, this is 572 bytes. Iflenis greater than this number, then the function does not send the data and returns -1. Otherwise, the UDP datagram would need to be fragmented.For TCP, the new data is queued for sending and
sock_fastwrite()returns the number of bytes that will be sent. The data may be transmitted immediately if enough data is in the buffer, or sufficient time has expired, or the user has explicitly usedsock_flushnext()to indicate this data should be flushed immediately. In either case, no guarantee of acceptance at the other end is possible.Parameters
s
dp
len
Maximum number of bytes to write to the socket.
Return value
Number of bytes written, or
-1if there was an error.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
sock_flush
void sock_flush( tcp_Socket *s );Description
sock_flush()will flush the unwritten portion of the TCP buffer to the network. No guarantee is given that the data was actually delivered. In the case of a UDP socket, no action is taken.
sock_flushnext()is recommended oversock_flush().Parameters
s
Return value
Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_flushnext, sock_fastwrite, sock_write, sockerr
sock_flushnext
void sock_flushnext( tcp_Socket *s );Description
Writing to TCP sockets does not guarantee that the data are actually transmitted or that the remote computer will pass that data to the other client in a timely fashion. Using a flush function will guarantee that
DCRTCP.LIBplaces the data onto the network. No guarantee is made that the remote client will receive that data.
sock_flushnext()is the most efficient of the flush functions. It causes the next function that sends data to the socket to flush, meaning the data will be transmitted immediately.Several functions imply a flush and do not require an additional flush:
sock_puts(), and sometimessock_putc()(when passed a \n).Parameters
s
Return value
Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_write, sock_fastread, sock_read, sockerr, sock_flush, sock_flushnext
sock_getc
int sock_getc( tcp_Socket *s );Description
Gets the next character from the socket. NOTE: This function blocks.
This function cannot be used on UDP sockets after
sock_recv_init()is called.Parameters
s
Return value
Character read or
-1if error.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
Example
do {
if (sock_bytesready( s ) > 0)putchar( sock_getc( s ));
} while (tcp_tick(s));
sock_gets
int sock_gets( tcp_Socket *s, char *text, int len );Description
Reads a string from a socket and replaces the CR or LF with a '\0'. If the string is longer than
len, the string is null terminated and the remaining characters in the string are discarded.To use
sock_gets(), you must first set ASCII mode using the functionsock_mode()or the macrotcp_set_ascii().This function cannot be used on UDP sockets after
sock_recv_init()is called.Parameters
s
text
len
Return value
0: Either the buffer is empty or the buffer has room and the connection
can get more data, but no '\r' or '\n' was read.>0: The length of the string.-1: Function was called with a UDP socket ( valid for Dynamic C 7.05 and later).Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_puts, sock_putc, sock_getc, sock_read, sock_write
Example
sock_mode( s, TCP_MODE_ASCII );
do {
if (sock_bytesready( s ) > 0) {
sock_gets( s, buffer, sizeof(buffer)-1 );
puts( buffer );
}
} while (tcp_tick( s );
sock_init
int sock_init(void);Description
This function initializes the packet driver and
DCRTCP.LIBusing the compiler defaults for configuration. This function must be called before using otherDCRTCP.LIBfunctions.The return value indicates whether the network is available. If the return code is 1or 3, then the network is not usable. If the return code is 2, then the network is usable because suitable fallbacks were defined; particularly
MY_IP_ADDRESS. It is only possible to get return codes 2 or 3 isUSE_DHCPis defined. Typically, return codes 2 or 3 mean that there is no DHCP server available within approximately 30 seconds from callingsock_init(). The timeout can be adjusted by setting the global variable_bootptimeoutto a suitable value before callingsock_init().If
USE_DHCPandMY_IP_ADDRESSare both defined, then by default the global variable_survivebootpwill be set to TRUE. If_survivebootpis set to FALSE before callingsock_init(), then the fallbacks will not be used. That is, return code 2 will never be returned.If you use
ucos2.lib, be sure to callOSInit()before callingsock_init().Return Value
0: OK.1: Ethernet packet driver initialization failed.2: DHCP failed, using fallback definitions.3: DHCP failed, no fallbacks defined.
Other: reserved.Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
sock_mode
word sock_mode( void *s, word mode );Description
Change some of the socket options. Depending on whether
sis a TCP or UDP socket, you may pass OR'd combinations of the following flags in the mode parameter. For a TCP socket, only theTCP_MODE_*flags are relevant. For a UDP socket, only theUDP_MODE_*flags are relevant. Do not use the wrong flags for the given socket type.Note: it is more convenient, faster, and safer to use the macro equivalent, if it is only desired to change one mode at a time. If you use this function, then you must specify the setting of all relevant flags (TCP or UDP).
The macros do not do socket locking so, strictly speaking, µC/OS users should call this function.
TCP Modes:
TCP_MODE_ASCII | TCP_MODE_BINARY (default)
TCP and UDP sockets are usually in binary mode which means an arbitrary stream of bytes is allowed (TCP is treated as a byte stream and UDP is treated as records filled with bytes.) The default is
TCP_MODE_BINARY.By changing the mode toTCP_MODE_ASCII, some of theDCRTCP.LIBfunctions will see a stream of records terminated with a newline character.In ASCII mode,
sock_bytesready()will return -1 until a newline-terminated string is in the buffer or the buffer is full.sock_puts()will append a newline to any output.sock_gets()(which should only be used in ASCII mode) removes the newline and null terminates the string.Macros:
tcp_set_binary(s)
tcp_set_ascii(s)TCP_MODE_NAGLE (default) | TCP_MODE_NONAGLE
The Nagle algorithm may substantially reduce network traffic with little negative effect on a user (In some situations, the Nagle algorithm even improves application performance.) The default is
TCP_MODE_NAGLE. This mode only affects TCP connections.Macros:
tcp_set_nagle(s)
tcp_set_nonagle(s)
UDP Modes:
UDP_MODE_CHK | UDP_MODE_NOCHK
Checksums are required for TCP, but not for UDP. The default is
UDP_MODE_CHK.If you are providing a checksum at a higher level, the low-level checksum may be redundant. The checksum for UDP can be disabled by selecting theUDP_MODE_NOCHKflag. Note that you do not control whether the remote computer will send checksums. If that computer does checksum its outbound data,DCRTCP.LIBwill check the received packet's checksum.Macros:
udp_set_chk(s)
udp_set_nochk(s)UDP_MODE_NOICMP (default) | UDP_MODE_ICMP
Marks this socket for receipt of ICMP error messages. The messages are queued like normal received datagrams, and read using
udp_recvfrom(), which returns -3 when ICMP messages are returned instead of normal datagrams. Only ICMP messages which are relevant to the current binding of the socket are queued.Macros:
udp_set_noicmp(s)
udp_set_icmp(s)UDP_MODE_NODICMP (default) | UDP_MODE_DICMP
Marks this socket as the default receiver of ICMP messages which cannot be assigned to a particular UDP socket. This would be used for UDP sockets that are used with many different
sendtoaddresses, since the ICMP message may refer to a message sent some time ago (with different destination address than the most recent). Only one UDP socket should be set with this mode.Macros:
udp_set_nodicmp(s)
udp_set_dicmp(s)Parameters
s
mode
New mode for specified socket.
Return Value
See Also
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
sock_perror
void sock_perror(void *s, const char * prefix);Description
Prints out the most recent error messages for a socket, and clear the errors. This calls
sockerr()andprintf(), so it should only be called for debugging a new application. The output is in the format:[TCP|UDP] socket (ipaddr:port -> ipaddr:port) msg1; msg2where
msg1and, possibly,msg2are the most recent error messages. The initial string is "TCP" or "UDP" for open sockets, or may be "Closed" if the socket is currently closed (either TCP or UDP). Up to two error codes may be queued to a socket.If there are no errors, nothing is printed.
Parameters
s
prefix
Pointer to text to add to generated messages, or
NULL.Library
See Also
sock_preread
int sock_preread( tcp_Socket *s, byte *dp, int len );Description
This function reads up to
lenbytes from the socket into the bufferdp. The bytes are not removed from the socket's buffer.Parameters
s
Pointer to a socket structure.
dp
len
Maximum number of bytes to preread.
Return value
0: No data waiting.-1: Error.>0: Number of preread bytes.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_fastread, sock_fastwrite, sock_read, sock_write
sock_putc
byte sock_putc( tcp_Socket *s, byte c );Description
A single character is placed on the output buffer. In the case of `\n', the buffer is flushed as described under
sock_flushnext. No other ASCII character expansion is performed.Note that
sock_putcusessock_write, and thus may block if the output buffer is full. Seesock_writefor more details.Parameters
s
c
Return value
Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_read, sock_write, sock_fastread, sock_fastwrite, sock_mode
sock_puts
int sock_puts( tcp_Socket *s, byte *dp );Description
A string is placed on the output buffer and flushed as described under
sock_flushnext(). If the socket is in ASCII mode, CR and LF are appended to the string. No other ASCII character expansion is performed. In binary mode, the string is sent as is.Note that
sock_puts()usessock_write(), and thus may block if the output buffer is full. Seesock_write()for more details.Parameters
s
dp
Buffer to read the string from.
Return value
≥
0: Length of string indp.-1: Function was called with a UDP socket (valid for Dynamic C 7.05 and later).Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_gets, sock_putc, sock_getc, sock_read, sock_write
sock_rbleft
int sock_rbleft( void *s );Description
Determines the number of bytes available in the receive buffer.
Parameters
s
Return value
Number of bytes available in the receive buffer.
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_rbsize, sock_rbused, sock_tbsize, sock_tbused, sock_tbleft
sock_rbsize
int sock_rbsize( void *s );Description
Determines the size of the receive buffer for the specified socket.
Parameters
s
Return value
The size of the receive buffer.
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_rbleft, sock_rbused, sock_tbsize, sock_tbused, sock_tbleft
sock_rbused
int sock_rbused( void *s );Description
Returns the number of bytes in use in the receive buffer for the specified socket.
Parameters
s
Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_rbleft, sock_tbsize, sock_tbused, sock_tbleft
sock_read
int sock_read( tcp_Socket *s, byte *dp, int len );Description
sock_read()will busywait untillenbytes are read or a socket error exists. Ifsock_yield()has been called, the user-defined function that is passed to it will be called in a tight loop whilesock_read()is busywaiting.This function cannot be used on UDP sockets after
sock_recv_init()is called.Parameters
s
dp
Buffer to store bytes that are read.
len
Maximum number of bytes to write into the buffer.
Return value
Number of bytes read: Success.
-1: Error.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_fastread, sock_fastwrite, sock_write, sockerr
Example
Note that
sock_fastread()andsock_read()do not necessarily return a complete or single line--they return blocks of bytes. In comparison,sock_getc()returns a single byte at a time and thus yields poor performance.
sock_recv
int sock_recv( sock_type *s, char *buffer, int len );Description
After a UDP socket is initialized with
udp_open()andsock_recv_init(),sock_recv()scans the buffers for any datagram received by that socket. This function is not available starting with Dynamic C 7.05 (see Section 2.3).Parameters
s
buffer
maxlength
Return value
>0: Length of datagram.0: No datagram found.-1: Receive buffer not initialized withsock_recv_init().Library
See also
sock_recv_from, sock_recv_init
Example using sock_recv()
sock_recv_from
int sock_recv_from( sock_type *s, long *hisip, word *hisport, char *buffer, int len);Description
After a UDP socket is initialized with
udp_open()andsock_recv_init(),sock_recv_from()scans the buffers for any datagram received by that socket and identifies the remote host's address. This function is not available starting with Dynamic C 7.05 (see Section 2.3).Parameters
s
hisip
IP of remote host, according to UDP header.
hisport
buffer
len
Return value
>0: Length of datagram received;0: No datagram;-1: Receive buffer was not initialized withsock_recv_init().Library
See also
sock_recv_init
int sock_recv_init( sock_type *s, void *space, word len);Description
This function is not available starting with Dynamic C 7.05 (see Section 2.3).
The basic socket reading functions (
sock_read(),sock_fastread(), etc.) are not adequate for all your UDP needs. The most basic limitation is their inability to treat UDP as a record service.A record service must receive distinct datagrams and pass them to the user program as such. You must know the length of the received datagram and the sender (if you opened in broadcast mode). You may also receive the datagrams very quickly, so you must have a mechanism to buffer them.
Once a socket is opened with
udp_open(), you can usesock_recv_init()to initialize that socket forsock_recv()andsock_recv_from(). Note thatsock_recv()and related functions areincompatiblewithsock_read(),sock_fastread(),sock_gets()andsock_getc(). Once you have usedsock_recv_init(), you can no longer use the older-style calls.
sock_recv_init()installs a large buffer area which gets segmented into smaller buffers. Whenever a UDP datagram arrives,DCRTCP.LIBstuffs that datagram into one of these new buffers. The new functions scan those buffers. You must select the size of the buffer you submit tosock_recv_init(); make it as large as possible, say 4K, 8K or 16K.For a sample program, see Example using sock_recv() listed under
sock_recv().Parameters
s
space
Buffer of temporary storage space to store newly received packets.
len
Return value
Library
See also
sock_resolved
int sock_resolved(void * s)Description
Check whether the socket has a valid destination hardware address. This is typically used for UDP sockets, but may also be used for TCP sockets. If this function returns zero (FALSE), then any datagrams you send using
udp_send()orudp_sendto()may not be transmitted because the destination hardware address is not known.If the current destination IP address of the socket is zero (i.e. the socket is passively opened), this function returns zero, since datagrams cannot be transmitted from a passively opened socket.
If
udp_bypass_arp()is in effect, the return value from this function is unaffected, however datagrams will still be sent to the specified hardware address (since the normal resolve process is bypassed).Note that a hardware address may become invalid after being valid, since the underlying ARP table may need to purge the entry. This would be rare, but if any UDP application needs to ensure that all packets are actually transmitted, which is a questionable goal since UDP is unreliable, then this function should be consulted before each send. If this function returns 0, then the UDP socket should be re-opened.
The hardware address may also be invalidated if
udp_sendto()is called with a different destination IP address, that has not been determined based on an incoming datagram.This function is not required for TCP sockets, since the TCP library handles these details internally.
Parameter
s
Pointer to open TCP or UDP socket
Return Value:
0: Destination hardware address not valid!0: Destination hardware address resolved OK.Library
See Also
udp_extopen, arpresolve_start, arpresolve_check, udp_waitopen, udp_sendto, udp_bypass_arp
sock_set_tos
void sock_set_tos(void* s, byte tos);Description
Set the IP "Type Of Service" field in outgoing packets for this socket. The given TOS will be in effect until the socket is closed. When a socket is opened (or re-opened), the TOS will be set to the default (
TCP_TOSorUDP_TOSas appropriate). If not overridden, the defaults are zero (IPTOS_DEFAULT) in both cases.Parameters
s
Pointer to open TCP or UDP socket.
tos
Type Of Service. This should be one of the following values:
·IPTOS_DEFAULT- Default service
·IPTOS_CHEAP- Minimize monetary cost
·IPTOS_RELIABLE- Maximize reliability
·IPTOS_CAPACIOUS- Maximize throughput
·IPTOS_FAST- Minimize delay
·IPTOS_SECURE- Maximize security.
Other value may be used (since TOS is just a number between 0 and 255), but this should only be done for experimental purposes.
Library
See Also
sock_set_ttl
void sock_set_ttl(void* s, byte ttl);Description
Set the IP "Time To Live" field in outgoing packets for this socket. The given TTL will be in effect until the socket is closed. When a socket is opened (or re-opened), the TTL will be set to the default (
TCP_TTLorUDP_TTLas appropriate). If not overridden, the defaults are 64 in both cases.Parameters
s
Pointer to open TCP or UDP socket.
ttl
Time To Live. This is a value between 1 and 255. A value of zero is also accepted, but will have undesirable consequences.
Library
See Also
sockstate
char *sockstate( void * s );Description
Returns a string that gives the current state for a socket.
Parameters
s
Return value
An ASCII message which represents the current state of the socket. These strings should not be modified.
"
Listen" indicates a passively opened socket that is waiting for a connection."
SynSent" and "SynRcvd" are connection phase intermediate states."
Established" states that the connection is complete."
EstClosing" "FinWait1" "FinWait2" "CloseWait" "Closing" "LastAck" "TimeWait" and "CloseMSL" are connection termination intermediate states."
Closed" indicates that the connection is completely closed."
UDP Socket" is always returned for UDP sockets because they are stateless."
Not an active socket" is a default value used when the socket is not recognized as UDP or TCP.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_established, sock_dataready
Example
char *p;
...
#ifdef DEBUG
if ( p = sockstate( s ))
printf("Socket state is '%s'\n\r", p );
#endif DEBUG
sock_tbleft
int sock_tbleft( void *s );Description
Gets the number of bytes left in the transmit buffer. If you do not wish to block, you may first query how much space is available for writing by calling this function before generating data that must be transmitted. This removes the need for your application to also buffer data.
Parameters
s
Return value
Number of bytes left in the transmit buffer.
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_rbsize, sock_rbused, sock_rbleft, sock_tbsize, sock_tbused
if ( sock_tbleft( s ) > 10 ) {
/* we can send up to 10 bytes without blocking or overflowing */
....
}
sock_tbsize
int sock_tbsize( void *s );Description
Determines the size of the transmit buffer for the specified socket.
Parameters
s
Return value
The size of the transmit buffer.
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_rbsize, sock_rbused, sock_rbleft, sock_tbleft, sock_tbused
sock_tbused
int sock_tbused( void *s );Description
Gets the number of bytes in use in the transmit buffer for the specified socket.
Parameters
s
Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_rbsize, sock_rbused, sock_rbleft, sock_tbsize, sock_tbleft
sock_tick
void sock_tick( void * s, int * optional_status_ptr );Description
This macro calls
tcp_tick()to quickly check incoming and outgoing data and to manage all the open sockets. If our particular socket,s, is either closed or made inoperative due to an error condition,sock_tick()sets the value of*optional_status_ptr(if the pointer is notNULL) to 1, then jumps to a local, user-supplied label,sock_err. If the socket connection is fine and the pointer is notNULL*optional_status_ptris set to 0.Parameters
s
optional_status_ptr
Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
sock_wait_closed
void sock_wait_closed(void * s, int seconds, int (*fptr)(), int* status);Description
This macro waits until a TCP connection is fully closed. Returns immediately for UDP sockets. On an error, the macro jumps to a local, user-supplied
sock_errlabel. Iffptrreturns non-zero the macro returns with the status word set to the value offptr`s return value.This macro has been deprecated in Dynamic C version 7.20.
Parameters
s
seconds
Number of seconds to wait before timing out. A value of zero indicates the macro should never time-out. A good value to use is
sock_delay, a system variable set on configuration. Typicallysock_delayis about 20 seconds, but can be set to something else inmain().fptr
Function to call repeatedly while waiting. This is a user-supplied function.
status
Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
sock_wait_established
void sock_wait_established(void* s, int seconds, int (*fptr)(), int* status);Description
This macro waits until a connection is established for the specified TCP socket, or aborts if a time-out occurs. It returns immediately for UDP sockets. On an error, the macro jumps to the local, user-supplied
sock_errlabel. Iffptrreturns non-zero, the macro returns.This macro has been deprecated in Dynamic C version 7.20.
Parameters
s
seconds
Number of seconds to wait before timing out. A value of zero indicates the macro should never time-out. A good value to use is
sock_delay, a system variable set on configuration. Typicallysock_delayis about 20 seconds, but can be set to something else inmain().fptr
Function to call repeatedly while waiting. This is a user-supplied function.
status
Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
sock_wait_input
void sock_wait_input(void* s, int seconds, int (*fptr)(), int* status);Description
Waits until input exists for functions such as
sock_read()andsock_gets(). As described undersock_mode(), if in ASCII mode,sock_wait_inputonly returns when a complete string exists or the buffer is full. It returns immediately for UDP sockets.On an error, the macro jumps to a local, user-supplied
sock_errlabel. Iffptrreturns non-zero, the macro returns.This macro has been deprecated in Dynamic C version 7.20.
Parameters
s
seconds
Number of seconds to wait before timing out. A value of zero indicates the macro should never time-out. A good value to use is
sock_delay, a system variable set on configuration. Typicallysock_delayis about 20 seconds, but can be set to something else inmain().fptr
Function to call repeatedly while waiting.
status
A pointer to the status word. If this parameter is
NULL, no status number will be available, but the macro will otherwise function normally. Typically the pointer will point to a local signed integer that is used only for status.statusmay be tested to determine how the socket was ended. A value of 1 means a proper close while a -1 value indicates a reset or abort.Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
sock_write
int sock_write( tcp_Socket *s, byte *dp, int len );Description
Writes up to
lenbytes fromdpon sockets. This function busywaits until either the buffer is completely written or a socket error occurs. Ifsock_yield()has been called, the user-defined function that is passed to it will be called in a tight loop whilesock_write()is busywaiting.For UDP,
sock_write()will send one (or more) records. For TCP, the new data may be transmitted if enough data is in the buffer or sufficient time has expired or the user has explicitly usedsock_flushnext()to indicate this data should be flushed immediately. In either case, there is no guarantee of acceptance at the other end.Parameters
s
dp
len
Maximum number of bytes to write to the buffer.
Return value
Number of bytes written or
-1on an error.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
sock_read, sock_fastwrite, sock_fastread, sockerr, sock_flush, sock_flushnext
sock_yield
int sock_yield( tcp_Socket *s, void (*fn)());Description
This function, if called prior to one of the blocking functions, will cause
fn,the user-defined function that is passed in as the second parameter, to be called repeatedly while the blocking function is in a busywait state.Parameters
s
fn
Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
tcp_clearreserve
void tcp_clearreserve( word port );Description
This function causes the
DCRTCP.LIBstack to handle a socket connection to the specified port normally. This undoes the action taken bytcp_reserveport().Parameters
port
Return value
Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
tcp_config
void tcp_config(char *name, char *value);Description
Sets TCP/IP stack parameters at runtime. It should not be called with open sockets.
Note that there are specific (and safer) functions for modifying some of the common parameters.
This function is deprecated. It is highly recommended that you do NOT use it, since it uses strings, hence taking up lots of root data storage.
Parameters
name
Setting to be changed. The possible parameters are:
MY_IP_ADDRESS: host IP address (usesethostid()instead)MY_NETMASKMY_GATEWAY: host's default gatewayMY_NAMESERVER: host's default nameserverMY_HOSTNAMEMY_DOMAINNAME: host's domain name (usesetdomainname()instead)value
Return value
Library
NET.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See Also
tcp_open, sock_close, sock_abort, sethostid, setdomainname, sethostname
tcp_extlisten
int tcp_extlisten( tcp_Socket *s, int iface, word lport, longword remip, word port, dataHandler_t datahandler, word reserved, long buffer, int buflen );Description
This function tells the TCP/IP engine that an incoming session for a particular port will be accepted. The
bufferandbuflenparameters allow a user to supply a socket buffer, instead of using a socket buffer from the pool.tcp_extlisten()is an extended version oftcp_listen().Parameters
s
Pointer to the socket's data structure.
iface
Local interface on which to open the socket (not yet implemented, use
IF_DEFAULTfor now).lport
remip
IP address to accept connections from or 0 for all.
port
Port to accept connections from or 0 for all.
datahandler
Function to call when data is received,
NULLfor placing data in the socket's receive buffer. Some details for implementation of this service have not been finalized, and it is recommended the user insert a value ofNULLfor the present time.reserved
Set to 0 for now. This parameter is for compatibility and possible future use.
buffer
Address of user-supplied socket buffer in xmem. This is the return value of
xalloc(). Ifbufferis 0, the socket buffer for this socket is pulled from the buffer pool defined by the macroMAX_TCP_SOCKET_BUFFERS.buflen
Length of user-supplied socket buffer.
Return value
Library
See also
tcp_extopen
int tcp_extopen(tcp_Socket* s, int iface, word lport, longword remip, word port, dataHandler_t datahandler, long buffer, int buflen);Description
Actively creates a session with another machine. The
bufferandbuflenparameters allow a user to supply a socket buffer, instead of using a socket buffer from the pool.tcp_extopen()is an extended version oftcp_open().s
Pointer to socket's data structure.
iface
Local interface on which to open the socket (not yet implemented, use
IF_DEFAULTfor now).lport
Our port, zero for the next one available in the range 1025-65536.
remip
port
datahandler
Function to call when data is received,
NULLfor placing data in the socket's receive buffer. Some details for implementation of this service have not been finalized, and it is recommended the user insert a value ofNULLfor the present time.buffer
Address of user-supplied socket buffer in xmem. This is the return value of
xalloc(). Ifbufferis 0, the socket buffer for this socket is pulled from the buffer pool defined by the macroMAX_TCP_SOCKET_BUFFERS.buflen
Length of user-supplied socket buffer.
Return value
0if open was not able resolve the remote computer's hardware address,!0otherwise.Library
See also
tcp_keepalive
int tcp_keepalive(tcp_Socket *s, long timeout);Description
Enable or disable TCP keepalives on a specified socket. The socket must already be open. Keepalives will then be sent after
timeoutseconds of inactivity. It is highly recommended to keeptimeoutas long as possible, to reduce the load on the network. Ideally, it should be no shorter than 2 hours. After the timeout is sent, andKEEPALIVE_WAITTIMEseconds pass, another keepalive will be sent, in case the first was lost. This will be retriedKEEPALIVE_NUMRETRYStimes. Both of these macros can be defined at the top of your program, overriding the defaults of 60 seconds, and 4 retries.Using keepalives is not a recommended procedure. Ideally, the application using the socket should send its own keepalives.
tcp_keepalive()is provided because telnet and a few other network protocols do not have a method of sending keepalives at the application level.Parameters
s
timeout
Period of inactivity, in seconds, before sending a keepalive or 0 to turn off keepalives.
Return value
Library
See also
sock_fastread, sock_fastwrite, sock_write, sockerr
tcp_listen
int tcp_listen( tcp_Socket *s, word lport, longword remip, word port, int (*signal_handler), word reserved );Description
This function tells
DCRTCP.LIBthat an incoming session for a particular port will be accepted. After a call totcp_listen(), the functionsock_established()(or the macrosock_wait_established) must be called to poll the connection until a session is fully established.It is possible for a connection to be opened, written to and closed between two calls to the function
sock_established(). To handle this case, callsock_bytesready()to determine if there is data to be read from the buffer.Multiple calls to
tcp_listen()to the same local port (lport) are acceptable and constitute theDCRTCP.LIBmechanism for supporting multiple incoming connections to the same local port. Each time another host attempts to open a session on that particular port, another one of the listens will be consumed until such time as all listens have become established sessions and subsequent remote host attempts will receive a reset.Parameters
s
lport
Port to listen on (the local port number).
remip
IP address of the remote host to accept connections from or 0 for all.
port
Port to accept connections from or 0 for all.
signal_handler
This function is called if the connection is either closed or reset. The parameter for
signal_handleris the pointer to a function which will be called when the socket is either closed or reset. Some details for implementation of this service have not been finalized, and it is recommended the user insert a value ofNULLfor the present time.reserved
Set to 0 for now. This parameter is for compatibility and possible future use.
Return value
Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
Example using tcp_listen()
tcp_open
int tcp_open( tcp_Socket *s, word lport, longword remip, word port, int (*signal_handler)());Description
This function actively creates a session with another machine. After a call to
tcp_open(), the functionsock_established()(or the macrosock_wait_established) must be called to poll the connection until a session is fully established.It is possible for a connection to be opened, written to and closed between two calls to the function
sock_established(). To handle this case, callsock_bytesready()to determine if there is data to be read from the buffer.Parameters
s
Pointer to a socket structure.
lport
Our local port. Use zero for the next available port in the range 1025-65536. A few applications will require you to use a particular local port number, but most network applications let you use almost any port with a certain set of restrictions. For example,
FINGERorTELNETclients can use any local port value, so pass the value of zero forlportand letDCRTCP.LIBpick one for you.remip
port
signal_handler
This function is called if the connection is either closed or reset. The parameter for
signal_handleris the pointer to a function which will be called when the socket is either closed or reset. Some details for implementation of this service have not been finalized, and it is recommended the user insert a value ofNULLfor the present time.Return value
0: Unable to resolve the remote computer's hardware address;!0otherwise.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
Example Using tcp_open()
tcp_reserveport
void tcp_reserveport( word port );Description
This function allows a connection to be established even if there is not yet a socket available. This is done by setting a parameter in the TCP header during the connection setup phase that indicates 0 bytes of data can be received at the present time. The requesting end of the connection will wait until the TCP header parameter indicates that data will be accepted.
The 2MSL waiting period for closing a socket is avoided by using this function.
The penalty of slower connection times on a controller that is processing a large number of connections is offset by allowing the program to have less sockets and consequently less RAM usage.
Parameters
port
Return value
Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
tcp_tick
int tcp_tick( void *s );Description
This function is a single kernel routine designed to quickly process packets and return as soon as possible.
tcp_tick()performs processing on all sockets upon each invocation: checking for new packets, processing those packets, and performing retransmissions on lost data. On most other computer systems and other kernels, performing these required operations in the background is often done by a task switch.DCRTCP.LIBdoes not use a tasker for its basic operation, although it can adopt one for the user-level services.Although you may ignore the returned value of
tcp_tick(), it is the easiest method to determine the status of the given socket.Parameters
s
Pointer to a socket. If
NULL, the returned value is always0.Return value
0: Connection reset or closed by other host orNULLwas passed in.!0: Connection is fine.Library
TCP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
tcp_open, sock_close, sock_abort, sock_tick
udp_bypass_arp
void udp_bypass_arp(udp_Socket *s, eth_address * eth);Description
Override the normal Address Resolution Protocol for this UDP socket. This is sometimes necessary for special purposes such as if the ethernet address is to remain fixed, or if the ethernet address is not obtainable using ARP. The great majority of applications should not use this function.
If ARP bypass is in effect for a UDP socket, then
udp_sendto()will never return the -2 return code.Parameters
s
eth
Pointer to override address. If
NULL, then resume normal operation i.e. use ARP to resolve ethernet addresses. Note that the specified ethernet address must be in static storage, since only the pointer is stored.Library
See Also
udp_sendto, udp_waitsend, sock_resolved
udp_close
void udp_close(udp_Socket *ds);Description
This function closes a UDP connection.
Parameters
ds
Pointer to socket's data structure.
Library
udp_extopen
int udp_extopen( udp_Socket *s, int iface, word lport, longword remip, word port, dataHandler_t datahandler, long buffer, int buflen );Description
This function is an extended version of
udp_open(). It opens a socket on a given network interface (iface) on a given local port (lport). Theifaceparameter is not currently supported and should beIF_DEFAULT. The remote end of the connection is specified byremipandport. The following table explains the possible combinations and what they mean.
The
bufferandbuflenparameters allow a user to supply a socket buffer, instead of using a socket buffer from the pool.If
remipis non-zero, then the process of resolving the correct destination hardware address is started. Datagrams cannot be sent untilsock_resolved()returns TRUE. If you attempt to send datagrams before this, then the datagrams may not get sent. The exception to this is ifremipis -1 (broadcast) in which case datagrams may be sent immediately after calling this function.
Parameters
s
Pointer to socket's data structure.
iface
Local interface on which to open the socket (not yet implemented--use
IF_DEFAULTfor now).lport
remip
Acceptable remote IP, or 0 for all.
port
Acceptable remote port, or 0 for all.
datahandler
Function to call when data is received,
NULLfor placing data in the socket's receive buffer.buffer
Address of user-supplied socket buffer in xmem. If
bufferis 0, the socket buffer for this socket is pulled from the buffer pool defined by the macroMAX_UDP_SOCKET_BUFFERS.buflen
Length of user-supplied socket buffer.
Return value:
!0: Success.0: Failure; error opening socket, e.g., a buffer could not be allocated.Library
See Also
udp_open
int udp_open( udp_Socket *s, word lport, longword remip, word port, dataHandler_t datahandler);Description
This function opens a UDP socket on the given local port (
lport). The remote end of the connection is specified byremipandport. The following table explains the possible combinations and what they mean.
If the remote host is set to a particular address, either host may initiate traffic. Multiple calls to
udp_open()withremipset to zero is a useful way of accepting multiple incoming sessions.Although multiple calls to
udp_open()may normally be made with the samelportnumber, only oneudp_open()should be made on a particularlportif theremipis set to -1. Essentially, the broadcast and nonbroadcast protocols cannot co-exist.Be sure that you have allocated enough UDP socket buffers with
MAX_UDP_SOCKET_BUFFERS. Note that this macro defaults to 0, so any usage ofudp_open()requires a definition ofMAX_UDP_SOCKET_BUFFERSin your program.Parameters
s
lport
remip
Acceptable remote IP, 0 to connect on first datagram, or -1 for broadcast.
port
Acceptable remote port, or 0 to connect on first datagram.
datahandler
Function to call when data is received.
NULLfor placing data in the socket's receive buffer.
Return value
0: Failure (e.g., a buffer could not be allocated).!0: Success.Library
UDP.LIB (Prior to DC 7.05, this was DCRTCP.LIB)
See also
udp_peek
int udp_peek(udp_Socket* s, _udp_datagram_info * udi);Description
Look into the UDP socket receive buffer to see if there is a datagram ready to be read using
udp_recvfrom(). This function does not remove the datagram from the buffer, but it allows the application to determine the full details about the next datagram, including whether the datagram was broadcast.The returned data is put in
*udi.udimust point to a valid data structure, or beNULL. The data structure is:typedef struct {
longword remip; // Remote host IP address
word remport; // Remote host port number
int len; // Length of datagram
byte flags; // Flags
byte iface; // Interface number
} _udp_datagram_info;The
flagsfield may have one of the following values:UDI_ICMP_ERROR This is an ICMP error entry.
UDI_TOS_MASK Type-of-service bit mask.
UDI_BROADCAST_LL Received on broadcast link-layer address.
UDI_BROADCAST_IP Received on broadcast network (IP) address.Parameters
s
udi
Where to store the returned information.
Return Value
1: A normal datagram is in the receive buffer.0: No datagram waiting.
-3: An ICMP error message is in the receive buffer - this will only be returned ifudiparameter is notNULL.Library
See Also
udp_recv
int udp_recv(udp_Socket* s, char* buffer, int len)Description
Receives a single UDP datagram on a UDP socket. If the buffer is not large enough for the datagram, the datagram is truncated, and the remainder discarded.
Parameters
s
Pointer to socket's data structure.
buffer
Buffer where the UDP datagram will be stored.
len
Return value
≥0: Number of bytes received.-1: No datagram waiting.<-1: Error.Library
See also
udp_recvfrom, udp_send, udp_sendto, udp_open
udp_recvfrom
int udp_recvfrom(udp_Socket* s, char* buffer, int len, longword* remip, word* remport);Description
Receive a single UDP datagram on a UDP socket. remip and remport should be pointers to the locations where the remote IP address and remote port from which the datagram originated are placed. If the buffer is not large enough for the datagram, then the datagram will be truncated, with the remainder being discarded.
If and only if the
UDP_MODE_ICMPorUDP_MODE_DICMPmodes are set for this socket, then a return code of -3 indicates that an ICMP error message is being returned in the buffer instead of a normal datagram. In this case,bufferwill contain fixed data in the form of a structure of type_udp_icmp_message. The definition of this structure is:typedef struct {
word myport; // Originating port on this host
byte icmp_type; // One of the ICMPTYPE_* values
byte icmp_code; // The corresponding ICMP code
} _udp_icmp_message;Please see
sock_modefor more information about the modesUDP_MODE_ICMPandUDP_MODE_DICMP.Parameters
s
Pointer to socket's data structure.
buffer
Buffer where the UDP datagram will be stored.
len
remip
IP address of the remote host of the received datagram.
remport
Port number of the remote host of the received datagram.
Return value
≥
0: Number of bytes received.-1: No datagram waiting.-2: Error - not a UDP socket.-3: The returned buffer contains an ICMP error which was queued previously.Library
See also
udp_recv, udp_send, udp_sendto, udp_open, udp_peek
udp_send
int udp_send(udp_Socket* s, char* buffer, int len);Description
Sends a single UDP datagram on a UDP socket. It will not work for a socket for which the
remipparameter toudp_open()was 0, unless a datagram has first been received on the socket. If theremipparameter toudp_open()was -1, the datagram will be send to the broadcast address.Parameters
s
Pointer to socket's data structure.
buffer
Buffer that contains the UDP datagram
len
Return value
≥
0: Number of bytes sent.-1: Failure.Library
See also
udp_sendto, udp_recv, udp_recvfrom, udp_open
udp_sendto
int udp_sendto(udp_Socket* s, char* buffer, int len, longword remip, word remport);Description
Sends a single UDP datagram on a UDP socket. It will send the datagram to the IP address and port specified by
remipandremport. Note that this function can be used on a socket that has been "connected" to a different remote host and port.Parameters
s
Pointer to socket's data structure.
buffer
Buffer that contains the UDP datagram.
len
remip
IP address of the remote host.
remport
Port number of the remote host.
Return value
≥
0: Success, number of bytes sent.-1: Failure.-2: Failed because hardware address not resolved.Library
See also
udp_send, udp_recv, udp_recvfrom, udp_open
udp_waitopen
int udp_waitopen( udp_Socket *s, int iface, word lport, longword remip, word port, dataHandler_t datahandler, long buffer, int buflen, longword millisecs );Description
This function is identical to
udp_extopen(), except that it waits a specified amount of time for the hardware address of the destination to be resolved.While waiting, this function calls
tcp_tick().Parameters
s
iface
Local interface on which to open the socket (not yet implemented so use
IF_DEFAULTfor now).lport
remip
Acceptable remote ip, or 0 for all.
port
Acceptable remote port, or 0 for all.
datahandler
Function to call when data is received,
NULLfor placing data in the sockets receive buffer.buffer
Address of user-supplied socket buffer in xmem, 0 to use a buffer from the socket buffer pool.
buflen
Length of user-supplied socket buffer.
millisecs
Maximum milliseconds to wait for the hardware address to be resolved.
Return Value
>0: Successfully opened socket.0: Timed out without resolving address.-1: Error opening socket (e.g., buffer could not be allocated).Library
See Also
udp_waitsend
int udp_waitsend(udp_Socket* s, char* buffer, int len, longword remip, word remport, word millisecs);Description
This is identical to
udp_sendto(), except that it will block for up to the specified amount of time waiting for the hardware address to be resolved. Normally, you should not have to specify more than 100ms for the time out. If it takes longer than this, the destination is probably unavailable.Parameters
s
UDP socket on which to send the datagram.
buffer
Buffer that contains the UDP datagram.
len
remip
IP address of the remote host.
remport
Port number of the remote host.
millisecs
Number of milliseconds to wait for hardware address resolution. Reasonable values are between 50 and 750 milliseconds.
Return Value
≥
0: Number of bytes sent.-1: Failure (invalid UDP socket etc.).-2: Failure (timed out, no datagram sent).Library
See Also
udp_sendto, udp_recvfrom, udp_bypass_arp
2.9 Macros
DISABLE_DNS
This macro disables DNS lookup. This prevents a UDP socket for DNS from being allocated, thus saving memory. Users may still call
resolve()with an IP address.
MAX_SOCKETS
This macro defines the number of sockets that will be allocated, not including the socket for DNS lookups. It defaults to 4. If libraries such as
HTTP.LIBorFTP_SERVER.LIBare used, you must provide enough sockets inMAX_SOCKETSfor them also. This macro has been replaced byMAX_TCP_SOCKET_BUFFERSandMAX_UDP_SOCKET_BUFFERS.
MAX_SOCKET_LOCKS
For µC/OS-II support. This macro defines the number of socket locks to allocate. It defaults to
MAX_TCP_SOCKET_BUFFERS+MAX_UDP_SOCKET_BUFFERS.This macro is necessary because we can no longer calculate the number of socket locks needed based on the number of socket buffers, now that the user can manage their own socket buffers.
MAX_TCP_SOCKET_BUFFERS
Starting with Dynamic C version 7.05, this macro determines the maximum number of TCP sockets with preallocated buffers. If
MAX_SOCKETSis defined, thenMAX_TCP_SOCKET_BUFFERSwill be assigned the value ofMAX_SOCKETSfor backwards compatibility. If neither macro is defined,MAX_TCP_SOCKET_BUFFERSdefaults to 4.
MAX_UDP_SOCKET_BUFFERS
Starting with Dynamic C version 7.05, this macro determines the maximum number of UDP sockets with preallocated buffers. It defaults to 0.
MY_DOMAIN
This macro is the initial value for the domain portion of the controller's address. At runtime, it can be overwritten by
tcp_config()andsetdomainname().
MY_GATEWAY
This macro gives the default value for the controllers default gateway. At runtime, it can be overwritten by
tcp_config().
MY_IP_ADDRESS
This macro is the default IP address for the controller. At runtime, it can be overwritten by
tcp_config()andsethostid().
MY_NAMESERVER
This macro is the default value for the primary name server. At runtime, it can be overwritten by
tcp_config().
MY_NETMASK
This macro is the default netmask for the controller. At runtime, it can be overwritten by
tcp_config().
SOCK_BUF_SIZE
This macro determines the size of the socket buffers. A TCP socket will have two buffers of size
SOCK_BUF_SIZE/2 for send and receive. A UDP socket will have a single socket of sizeSOCK_BUF_SIZE. Both types of sockets take the same total amount of buffer space. This macro has been replaced byTCP_BUF_SIZEandUDP_BUF_SIZE.
TCP_BUF_SIZE
Starting with Dynamic C 7.05, TCP and UDP socket buffers are sized separately.
TCP_BUF_SIZEdefines the buffer sizes for TCP sockets. It defaults to 4096 bytes. Backwards compatibility exists with earlier version of Dynamic C: ifSOCK_BUF_SIZEis defined,TCP_BUF_SIZEis assigned the value ofSOCK_BUF_SIZE. IfSOCK_BUF_SIZEis not defined, buttcp_MaxBufSizeis, thenTCP_BUF_SIZEwill be assigned the value oftcp_MaxBufSize*2.
tcp_MaxBufSize
This use of this macro is deprecated in Dynamic C version 6.57 and higher; it has been replaced by
SOCK_BUF_SIZE.In Dynamic C versions 6.56 and earlier,
tcp_MaxBufSizedetermines the size of the input and output buffers for TCP and UDP sockets. Thesizeof(tcp_Socket)will be about 200 bytes more than doubletcp_MaxBufSize. The optimum value for local Ethernet connections is greater than the Maximum Segment Size (MSS). The MSS is 1460 bytes. You may want to lowertcp_MaxBufSize, which defaults to 2048 bytes, to reduce RAM usage. It can be reduced to as little as 600 bytes.
tcp_MaxBufSizewill work slightly differently in Dynamic C versions 6.57 and higher. In these later versions the buffer for the UDP socket will betcp_MaxBufSize*2, which is twice as large as before.
UDP_BUF_SIZE
Starting with Dynamic C 7.05, TCP and UDP socket buffers are sized separately.
UDP_BUF_SIZEdefines the buffer sizes for UDP sockets. It defaults to 4096 bytes. Backwards compatibility exists with earlier version of Dynamic C: ifSOCK_BUF_SIZEis defined,UDP_BUF_SIZEis assigned the value ofSOCK_BUF_SIZE. IfSOCK_BUF_SIZEis not defined, buttcp_MaxBufSizeis, thenUDP_BUF_SIZEwill be assigned the value oftcp_MaxBufSize*2.
| Z-World http://www.zworld.com Voice: 530.757.3737 Fax: 530.757.3792 or 530.753.5141 sales@zworld.com |