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

📄 tcpip.sgml

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 SGML
📖 第 1 页 / 共 3 页
字号:
</PARA>
<PROGRAMLISTING>int tftp_client_get(char *filename,
		    char *server,
		    int port,
		    char *buf,
		    int len,
		    int mode,
		    int *err);

int tftp_client_put(char *filename,
		    char *server,
		    int port,
		    char *buf,
		    int len,
		    int mode,
		    int *err);
</PROGRAMLISTING>
<PARA>Currently <varname>server</varname> can only be a numeric IPv4 or
IPv6 address. The resolver is currently not used, but it is planned to
add this feature (patches welcome). If <varname>port</varname> is zero
the client connects to the default TFTP port on the server. Otherwise
the specified port is used.
</PARA>
<PARA> 
The deprecated API is:
<PROGRAMLISTING>int tftp_client_get(char *filename,
		    struct sockaddr_in *server,
		    char *buf,
		    int len,
		    int mode,
		    int *err);

int tftp_client_put(char *filename,
		    struct sockaddr_in *server,
		    char *buf,
		    int len,
		    int mode,
		    int *err);
</PROGRAMLISTING>
</PARA>
<PARA>
The <varname>server</varname> should contain the address of the
server to contact. If the <varname>sin_port</varname> member of the
structure is zero the default TFTP port is used. Otherwise the
specified port is used.
</PARA>
<PARA>
Both API's report errors in the same way. The functions return a value
of -1 and <varname>*err</varname> will be set to one of the
following values:
</PARA>
<PROGRAMLISTING>
#define	TFTP_ENOTFOUND   1   /* file not found */
#define	TFTP_EACCESS     2   /* access violation */
#define	TFTP_ENOSPACE    3   /* disk full or allocation exceeded */
#define	TFTP_EBADOP      4   /* illegal TFTP operation */
#define	TFTP_EBADID      5   /* unknown transfer ID */
#define	TFTP_EEXISTS     6   /* file already exists */
#define	TFTP_ENOUSER     7   /* no such user */
#define TFTP_TIMEOUT     8   /* operation timed out */
#define TFTP_NETERR      9   /* some sort of network error */
#define TFTP_INVALID    10   /* invalid parameter */
#define TFTP_PROTOCOL   11   /* protocol violation */
#define TFTP_TOOLARGE   12   /* file is larger than buffer */
</PROGRAMLISTING>
<PARA>If there are no errors the return value is the number of bytes
transfered.
</PARA>

<PARA>The server is more complex.  It requires a filesystem implementation
to be supplied by the user, and attached to the tftp server by means
of a vector of function pointers:</PARA>
<PROGRAMLISTING>struct tftpd_fileops {
             int (&ast;open)(const char &ast;, int);
             int (&ast;close)(int);
             int (&ast;write)(int, const void &ast;, int);
             int (&ast;read)(int, void &ast;, int);
};</PROGRAMLISTING>
<PARA>These functions have the obvious semantics.  The structure
describing the filesystem is an argument to the <function>tftpd_start</function>:
<PROGRAMLISTING>
int tftp_start(int port,
               struct tftpd_fileops *ops);
</PROGRAMLISTING>
</PARA>
<PARA>The first argument is the port to use for the server. If this
port number is zero, the default TFTP port number will be used. The
return value from <function>tftpd_start</function> is a handle which
can be passed to <function>tftpd_stop</function>. This will kill the
tftpd thread. Note that this is not a clean shutdown. The thread will
simply be killed. <function>tftpd_stop</function> will attempt to
close the sockets the thread was listening on and free some of its
allocated memory. But if the thread was actively transferreing data at
the time <function>tftpd_stop</function> is called, it is quite likely
some memory and a socket will be leaked. Use this function with
caution (or implement a clean shutdown and please contribute the code
back :-).
</PARA>

<PARA>There are two CDL configuration options that control how many
servers on how many different ports tftp can be
started. CYGSEM_NET_TFTPD_MULTITHREADED, when enabled, allows multiple
tftpd threads to operate on the same port number. With only one
thread, while the thread is active transferring data, new requests for
transfers will not be served until the active transfer is
complete. When multiple threads are started on the same port, multiple
transfers can take place simultaneous, up to the number of threads
started. However a semaphore is required to synchronise the
threads. This semaphore is required per port. The CDL option
CYGNUM_NET_TFTPD_MULTITHREADED_PORTS controls how many different port
numbers multithreaded servers can service.
</PARA>
<PARA>If CYGSEM_NET_TFTPD_MULTITHREADED is not enabled, only one
thread may be run per port number. But this removes the need for a
semaphore and so CYGNUM_NET_TFTPD_MULTITHREADED_PORTS is not required
and unlimited number of ports can be used. </PARA>

<PARA>It should be noted that the TFTPD does not perform any form of
file locking. When multiple servers are active, it is assumed the
underlying filesystem will refuse to open the same file multiple
times, operate correctly with simultaneous read/writes to the same
file, or if you are unlucky, corrupt itself beyond all repair.</PARA>
 
<PARA>When IPv6 is enabled the tftpd thread will listen for requests
from both IPv4 and IPv6 addresses.</PARA>

<PARA>As discussed in the description of the tftp_server_test
above, an example filesystem is provided in
<filename>net/common/<REPLACEABLE>VERSION</REPLACEABLE>/src/tftp_dummy_file.c</filename>
for
use by the tftp server test.  The dummy filesystem is not a supported
part of the network stack, it exists purely for demonstration purposes.</PARA>
</SECT1>
<SECT1 id="net-common-dhcp">
<TITLE>DHCP</TITLE>
<PARA>This API publishes a routine to maintain DHCP state, and a
semaphore that is signalled when a lease requires attention: this
is your clue to call the aforementioned routine.</PARA>
<PARA>The intent with this API is that a simple DHCP client thread,
which maintains the state of the interfaces, can go as follows:
(after <function>init_all_network_interfaces()</function> is
called from elsewhere)</PARA>
<PROGRAMLISTING>while ( 1 ) {
        while ( 1 ) {
            cyg_semaphore_wait( &amp;dhcp_needs_attention );
            if ( ! dhcp_bind() ) // a lease expired
                break; // If we need to re-bind
        }
        dhcp_halt(); // tear everything down
        init_all_network_interfaces(); // re-initialize
}</PROGRAMLISTING>
<PARA>and if the application does not want to suffer the overhead
of a separate thread and its stack for this, this functionality
can be placed in the app&rsquo;s server loop in an obvious fashion.
 That is the goal of breaking out these internal elements.  For example,
some server might be arranged to poll DHCP from time to time like
this:</PARA>
<PROGRAMLISTING>while ( 1 ) {
    init_all_network_interfaces();
    open-my-listen-sockets();
    while ( 1 ) {
       serve-one-request();
       // sleeps if no connections, but not forever; 
       // so this loop is polled a few times a minute...
       if ( cyg_semaphore_trywait( &amp;dhcp_needs_attention )) {
             if ( ! dhcp_bind() ) {
                 close-my-listen-sockets();
                 dhcp_halt();
                 break;
             }
       }
    }
}</PROGRAMLISTING>
<PARA>If the configuration option CYGOPT_NET_DHCP_DHCP_THREAD
is defined, then eCos provides a thread as described initially.
Independent of this option, initialization of the interfaces still
occurs in <function>init_all_network_interfaces()</function> and
your startup code can call that.  It will start the DHCP management
thread if configured.  If a lease fails to be renewed, the management
thread will shut down all interfaces and attempt to initialize all
the interfaces again from scratch.  This may cause chaos in the
app, which is why managing the DHCP state in an application aware
thread is actually better, just far less convenient for testing.</PARA>

<PARA>If the configuration option CYGOPT_NET_DHCP_OPTION_HOST_NAME
is defined, then the TAG_HOST_NAME DHCP option will be included
in any DHCP lease requests.  The text for the hostname is set by
calling <function>dhcp_set_hostname()</function>.  Any DHCP lease requests
made prior to calling <function>dhcp_set_hostname()</function> will not
include the TAG_HOST_NAME DHCP option.  The configuration option
CYGNUM_NET_DHCP_OPTION_HOST_NAME_LEN controls the maximum length allowed
for the hostname.  This permits the hostname text to be determined at
run-time.  Setting the hostname to the empty string will have the effect
of disabling the TAG_HOST_NAME DHCP option.</PARA>
<PARA>If the configuration option CYGOPT_NET_DHCP_OPTION_DHCP_CLIENTID_MAC
is defined, then the TAG_DHCP_CLIENTID DHCP option will be included
in any DHCP lease requests.  The client ID used will be the current
MAC address of the network interface.</PARA>

<PARA>The option CYGOPT_NET_DHCP_PARM_REQ_LIST_ADDITIONAL allows
additional DHCP options to be added to the request sent to the DHCP
server. This option should be set to a comma separated list of options.
</PARA>

<PARA> The option CYGOPT_NET_DHCP_PARM_REQ_LIST_REPLACE is similar to
CYGOPT_NET_DHCP_PARM_REQ_LIST_ADDITIONAL but in this case it
completely replaces the default list of options with the configured
set of comma separated options.</para>
</SECT1>
</CHAPTER>
    &net-common-tcpip-manpages-sgml;
</PART>

⌨️ 快捷键说明

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