跳轉到內容

Aros/開發者/NIC驅動程式

來自華夏公益教科書,開放的書籍,開放的世界
Aros華夏公益教科書的導航欄
Aros使用者
Aros使用者文件
Aros使用者常見問題解答
Aros使用者應用程式
Aros使用者DOS Shell
Aros/使用者/AmigaLegacy
Aros開發文件
Aros開發者文件
從AmigaOS/SDL移植軟體
Zune初學者
Zune .MUI類
SDL初學者
Aros開發者構建系統
特定平臺
Aros x86完整系統HCL
Aros x86音訊/影片支援
Aros x86網路支援
Aros Intel AMD x86安裝
Aros儲存支援IDE SATA等
Aros Poseidon USB支援
x86-64支援
摩托羅拉68k Amiga支援
Linux和FreeBSD支援
Windows Mingw和MacOSX支援
Android支援
Arm Raspberry Pi支援
PPC Power Architecture
其他
Aros公共許可證
create socket
set sock addr
set sock port
open socket
send socket ( request_string )
receive result
#include <proto/socket.h>
#include <bsdsocket/socketbasetags.h>

bsdsocket.library在您啟動AROSTCP後會在記憶體中建立。這些包括的將提供它的連結。

#include <proto/exec.h>
struct Library * SocketBase = NULL;
int h_errno = 0;
extern int errno;

然後在初始化程式碼中

if(!(SocketBase = OpenLibrary("bsdsocket.library", 4 ))) {
SDLNet_SetError("No TCP/IP Stack running!\n");
return(-1);
}

if( SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (IPTR)&errno,
SBTM_SETVAL(SBTC_HERRNOLONGPTR), (IPTR)&h_errno, TAG_DONE )) {
SDLNet_SetError("Error initializing bsdsocket\n");
return(-1);
}

將網路應用程式的包含目錄更改為$(AROS_DEVELOPMENT)/netincludes,必須將#include <bsdsocket.h>更改為include <proto/bsdsocket.h>,bsdsocket.library在libs:中不存在作為二進位制檔案。它是您執行“startnet”後動態建立的。

將SocketBase重新定義為一個非全域性變數,例如執行緒特定上下文的欄位。例如

#define SocketBase my_thread_context->socket_base

查看了Task結構,它有tc_UserData,正是我需要的,我可以使用它來儲存每個任務的SocketBase。這種方法將起作用,即使我想在主程式中使用套接字。如果有人感興趣,我建立了這個小標頭檔案

#ifndef TASKSOCKBASE_H
#define TASKSOCKBASE_H

/*
 * Per-task socketbase using tc_UserData
 */

#include <proto/exec.h>

#define SocketBase FindTask(NULL)->tc_UserData
#define __BSDSOCKET_NOLIBBASE__
#include <proto/bsdsocket.h>

#endif

在所有地方包含它,而不是proto/bsdsocket.h,並像往常一樣使用SocketBase。

WaitSelect()的工作原理與select()相同,將這裡貼上程式碼部分,它失敗了……sys/select.h WaitSelect只能用於套接字,不能用於DOS檔案控制代碼。在Unix中,它們被統一處理,但在Amiga中,您必須對檔案控制代碼和套接字使用不同的程式碼路徑。

#ifndef select(nfds,rfds,wfds,efds,timeout)
#define select(nfds,rfds,wfds,efds,timeout) WaitSelect(nfds,rfds,wfds,efds,timeout,NULL)
#endif

並測試選擇

struct timeval timeout;
int socket_d;
struct fd_set client_d;

//set to 3 mins
timeout.tv_sec = 3 * 60;
timeout.tv_usec = 0;

do
{

rc = select(socket_d + 1, &client_d, NULL, NULL, &timeout);

/* Check to see if the select call failed. */
if (rc < 0)
{
perror(" select() failed");
break;
}

/* Check to see if the 3 minute time out expired. */
if (rc == 0)
{
printf(" select() timed out. End program.\n");
break;
}
} 

參考資料

[編輯 | 編輯原始碼]

socket—建立通訊端點

     #include <sys/types.h>
     #include <sys/socket.h>
 
     int socket(int domain, int type, int protocol)
    Socket() creates an endpoint for communication and returns a
    descriptor.

    The domain parameter specifies a communications domain within which
    communication will take place; this selects the protocol family
    which should be used.  These families are defined in the include
    file <sys/socket.h>.  The currently understood formats are

         AF_UNIX         (UNIX internal protocols),
         AF_INET         (ARPA Internet protocols),
         AF_ISO          (ISO protocols),
         AF_NS           (Xerox Network Systems protocols), and
         AF_IMPLINK      (IMP ``host at IMP link layer).

    AROS AMITCP/IP currently supports only AF_INET protocol family.

    The socket has the indicated type, which specifies the semantics of
    communication.  Currently defined types are:

         SOCK_STREAM
         SOCK_DGRAM
         SOCK_RAW
         SOCK_SEQPACKET
         SOCK_RDM

    A SOCK_STREAM type provides sequenced, reliable, two-way connection
    based byte streams.  An out-of-band data transmission mechanism
    may be supported.  A SOCK_DGRAM socket supports datagrams
    (connectionless, unreliable messages of a fixed (typically small)
    maximum length).  A SOCK_SEQPACKET socket may provide a sequenced,
    reliable, two-way connection-based data transmission path for
    datagrams of fixed maximum length; a consumer may be required to
    read an entire packet with each read system call.  This facility
    is protocol specific, and presently implemented only for PF_NS.
    SOCK_RAW sockets provide access to internal network protocols
    and interfaces.  The types SOCK_RAW, which is available only to
    the super-user, and SOCK_RDM, which is planned, but not yet
    implemented, are not described here.

    The protocol specifies a particular protocol to be used with the
    socket.  Normally only a single protocol exists to support a
    particular socket type within a given protocol family.  However,
    it is possible that many protocols may exist, in which case a
    particular protocol must be specified in this manner.  The
    protocol number to use is particular to the "communication domain"
    in which communication is to take place.

    Sockets of type SOCK_STREAM are full-duplex byte streams, similar
    to pipes.  A stream socket must be in a connected state before any
    data may be sent or received on it.  A connection to another
    socket is created with a connect() call.  Once connected, data may
    be transferred using recv() and send() or their variant calls.
    When a session has been completed a CloseSocket() may be
    performed.  Out-of-band data may also be transmitted as described
    in send() and received as described in recv().

    The communications protocols used to implement a SOCK_STREAM insure
    that data is not lost or duplicated.  If a piece of data for which
    the peer protocol has buffer space cannot be successfully
    transmitted within a reasonable length of time, then the
    connection is considered broken and calls will indicate an error
    with -1 returns and with ETIMEDOUT as the specific error code (see
    Errno()).  The protocols optionally keep sockets "warm" by forcing
    transmissions roughly every minute in the absence of other
    activity.  An error is then indicated if no response can be
    elicited on an otherwise idle connection for a extended period
    (e.g. 5 minutes).

    SOCK_SEQPACKET sockets employ the same system calls as SOCK_STREAM
    sockets.  The only difference is that recv() calls will return
    only the amount of data requested, and any remaining in the
    arriving packet will be discarded.

    SOCK_DGRAM and SOCK_RAW sockets allow sending of datagrams to
    correspondents named in send() calls.  Datagrams are generally
    received with recvfrom(), which returns the next datagram with its
    return address.

    An IoctlSocket() call can be used to specify a task to receive a
    SIGURG signal when the out-of-band data arrives.  It may also
    enable non-blocking I/O and asynchronous notification of I/O events
    via SIGIO.

    The operation of sockets is controlled by socket level options.
    These options are defined in the file <sys/socket.h>.
    setsockopt() and getsockopt() are used to set and get
    options, respectively.

返回值

[編輯 | 編輯原始碼]
    A -1 is returned if an error occurs, otherwise the return value is
    a descriptor referencing the socket.

    The socket() call fails if:
   [EPROTONOSUPPORT]
         The protocol type or the specified protocol is not supported
         within this domain.

   [EMFILE]
         The per-process descriptor table is full.

   [EACCESS]
         Permission to create a socket of the specified type and/or
         protocol is denied.

   [ENOBUFS]
         Insufficient buffer space is available.  The socket cannot be
         created until sufficient resources are freed.

    socket() calls the fdCallback() with action codes FDCB_CHECK and
    FDCB_ALLOC to check and mark the new descriptor as allocated
    if the callback is defined.  See SocketBaseTagList() for more
    information on fdCallback().

一些示例程式碼教程

SocketBaseTagList—Set/Get SocketBase attributes.

    #include <amitcp/socketbasetags.h>

    ULONG SocketBaseTagList(struct TagItem * taglist);

    ULONG SocketBaseTags(ULONG tag, ...);

    Set or get a list of (mostly) SocketBase instance dependent
    attributes from the AMITCP/IP.

    These functions expect as their argument a standard tag list, one
    or several array of struct TagItem as defined in the header file
    <utility/tagitem.h>. The structure contains two fields: ti_Tag
    and ti_Data.  The ti_Tag field contains tag code, which determines
    what the SocketBaseTagList() should do with its argument, the
    ti_Data field.

    The include file <amitcp/socketbasetags.h> defines macros for base
    tag code values.  Base tag code macros begin with `SBTC_' (as
    Socket Base Tag Code).  The base tag value defines what data item
    the tag item refers.

    The tag code contains other information besides the referred data
    item.  It controls, whether the SocketBaseTagList() should set or
    get the appropriate parameter, and whether the argument of the tag
    in question is passed by value or by reference.

    The include file <amitcp/socketbasetags.h> defines the following
    macros, which are used to construct the ti_Tag values from the base
    tag codes:
         SBTM_GETREF(code) - get by reference
         SBTM_GETVAL(code) - get by value
         SBTM_SETREF(code) - set by reference
         SBTM_SETVAL(code) - set by value

    If the actual data is stored directly into the ti_Data field, you
    should use the 'by value' macros, SBTM_GETVAL() or SBTM_SETVAL().
    However, if the ti_Data field contains a pointer to actual data,
    you should use the 'by reference' macros, SBTM_GETREF() or
    SBTM_SETREF().  In either case the actual data should always
    be a LONG aligned to even address.

    According the used tag naming scheme a tag which has "PTR" suffix
    takes an pointer as its argument.  Don't mix the pointer arguments
    with 'by reference' argument passing.  It is possible to pass a
    pointer by reference (in which case the ti_Data is a pointer to
    the actual pointer).

    The list of all defined base tag codes is as follows:

   SBTC_BREAKMASK
         Tag data contains the INTR signal mask.  If the calling task
         receives a signal in the INTR mask, the AMITCP/IP interrupts
         current function calls and returns with the error code EINTR.
         The INTR mask defaults to the CTRL-C signal (SIGBREAKF_C,
         bit 12).

   SBTC_DTABLESIZE
         Socket Descriptor Table size. This defaults to 64.

   SBTC_ERRNO
         The errno value. The values are defined in <sys-errno.h>.

   SBTC_ERRNOBYTEPTR
   SBTC_ERRNOWORDPTR
   SBTC_ERRNOLONGPTR
   SBTC_ERRNOPTR(size)
         Set (only) the pointer to the errno variable defined by the
         program.  AMITCP/IP defines a value for this by default, but
         the application must set the pointer (and the size of the
         errno) with one of these tags, if it wishes to access the
         errno variable directly.

         The SBTC_ERRNOPTR(size) is a macro, which expands to one of
         the other (BYTE, WORD or LONG) tag codes, meaning that only
         1, 2 and 4 are legal size values.

         The NetLib:autoinit.c sets the errno pointer for the
         application, if the application is linked with it.

   SBTC_ERRNOSTRPTR
         Returns an error string pointer describing the errno value
         given on input. You can not set the error message, only get
         is allowed.

         On call the ti_Data must contain the error code number.  On
         return the ti_Data is assigned to the string pointer.
         (*ti_Data, if passed by reference).  See the file
         <sys-errno.h> for symbolic definitions for the errno codes.

   SBTC_FDCALLBACK
         A callback function pointer for coordination of file
         descriptor usage between AMITCP/IP and link-library.  By
         default no callback is called and the value of this pointer
         is NULL.  The prototype for the callback function is:

         int error = fdCallback(int fd, int action);

        where
        error
              - 0 for success or one of the error codes in
              <sys-errno.h> in case of error. The AMITCP/IP API
              function that calls the callback usually returns the
              error back to the caller without any further
              modification.

        fd
              - file descriptor number to take action on.

        action
              - one of the action codes, which are defined in the
              header file <amitcp-socketbasetags.h>) as follows:

             FDCB_FREE
                   - mark the fd as unused on the link library
                   structure. If fd represents a file handled by the
                   link library, the error ENOTSOCK should be returned.

             FDCB_ALLOC
                   - mark the fd allocated as a socket.

             FDCB_CHECK
                   -check if the fd is free. If an error is returned,
                   the fd is marked as used in the AMITCP/IP
                   structures.

         The AMITCP/IP calls the callback every time a socket
         descriptor is allocated or freed. AMITCP/IP uses the
         FDCB_CHECK before actual allocation to check that it
         agrees with the link library on the next free descriptor
         number.  Thus the link library doesn't need to tell the
         AMITCP/IP if it creates a new file handle in open(), for
         example.

         See file _chkufb.c on the net.lib sources for an example
         implementation of the callback function for the SAS/C.

   SBTC_HERRNO
         The name resolver error code value. Get this to find out why
         the gethostbyname() or gethostbyaddr() failed. The values are
         defined in <netdb.h>.

   SBTC_HERRNOSTRPTR
         Returns host error string for error number in tag data.  Host
         error is set on unsuccessful gethostbyname() and
         gethostbyaddr() calls. See the file <netdb.h> for the
         symbolic definitions for the herrno valus.

         Notes for the SBTC_ERRNOSTRPTR apply also to this tag code.

   SBTC_IOERRNOSTRPTR
         Returns an error string for standard AmigaOS I/O error number
         as defined in the header file <exec-errors.h>.  Note that the
         error number taken by this tag code is positive, so the error
         codes must be negated (to be positive).  The positive error
         codes depend on the particular IO device, the standard
         Sana-II error codes can be retrieved by the tag code
         SBTC_S2ERRNOSTRPTR.

         Notes for the SBTC_ERRNOSTRPTR apply also to this tag code.

   SBTC_LOGFACILITY
         Facility code for the syslog messages as defined in
         <sys/syslog.h>.  Defaults to LOG_USER.

   SBTC_LOGMASK
         Sets the filter mask of the syslog messages.  By default the
         mask is 0xff, meaning that all messages are passed to the log
         system.

   SBTC_LOGSTAT
         Syslog options defined in <sys/syslog.h>.

   SBTC_LOGTAGPTR
         A pointer to a string which is used by Syslog() to mark
         individual syslog messages. This defaults to NULL, but is set
         to the name of the calling program by the autoinit code in
         netlib:autoinit.c.  This is for compatibility with pre-3.0
         programs.

   SBTC_S2ERRNOSTRPTR
         Returns an error string for a Sana-II specific I/O error code
         as defined in the header file <devices-sana2.h>.

         Notes for the SBTC_ERRNOSTRPTR apply also to this tag code.

   SBTC_S2WERRNOSTRPTR
         Returns an error string for a Sana-II Wire Error code as
         defined in the header file <devices-sana2.h>.

         Notes for the SBTC_ERRNOSTRPTR apply also to this tag code.

   SBTC_SIGEVENTMASK
         Tag data contains the signal mask to be sent to the
         application whenever notification about socket events is in
         order.  The default value for this is zero, inhibiting any
         event notifications.  The application must set this mask if
         it desires to be notified about asynchronous socket events.
         When the application receives the signal specified in the
         mask, it can use the function GetSocketEvents() to find out
         what happened.

   SBTC_SIGIOMASK
         The signals specified in the mask in the tag data are sent to
         the calling task when asynchronous I/O is to be notified. The
         default value is zero, i.e., no signals are sent. The signals
         in the mask are sent whenever something happens on the
         socket. This mechanism is compatible with the Unix SIGIO
         signal.

         Since AmigaOS signals may get combined, one signal may include
         notification for originally distinct events on the socket.
         One example of this is the reception of data and connection
         closure.

         Usage of the socket events (see GetSocketEvents()) is
         recommended over this because of the problem described above.

   SBTC_SIGURGMASK
         The signals specified in the mask in the tag data are sent to
         the calling task when notification about urgent data arrives.
         The default value is zero, i.e. no signals are sent. This
         mechanism is compatible with the Unix SIGURG signal.

         Note that this signal does not indicate the arrival of the
         actual out-of-band data. If the receive buffer of the socket
         is full, the urgent data can't even be received. Because of
         this the application may need to read some normal data off
         the socket before it can read the urgent data.

    Returns 0 on success, and a (positive) index of the failing tag on
    error.  Note that the value 1 means first TagItem, 2 the second
    one, and so on.  The return value is NOT a C-language index, which
    are 0 based.
extern LONG WaitSelect(rest);

int select(int nfds,fdset *readfds,rest) just like the header
{
return WaitSelect(rest);
}
</soruce>

==Blocking==

if your problem was O_NONBLOCK than why dont you actually use that setnonblocking()
function to enable non-blocking I/O instead of directly calling fcntl()????

also you may want to use O_NDELAY
O_NONBLOCK and O_NDELAY are same if you can use O_NDELAY

<syntaxhighlight lang="c">
int setNonblocking(int fd)
{
int flags;

/* If they have O_NONBLOCK, use the Posix way to do it */
#if defined(O_NONBLOCK)
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
flags = 0;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#else
/* Otherwise, use the old way of doing it */
flags = 1;
return ioctl(fd, FIOBIO, &flags);
#endif
}

IoctlSocket(socket, FIONBIO, (char *) &val);
d   domain
t   type
p   protocol
n   name
nl  namelen
l   level
r   request
a   arg
o   optname
ov  optval
ol  optlen
m   msg
l   length
f   flags

socket(d,t,p)               ex. s=socket(domain, type, protocol)
bind(s,n,nl)                ex. success = bind(s, name, namelen)
listen(s,b)
accept(s,a,al)
connect(s,n,nl)             ex. success = connect(s, name, namelen)
sendto(s,m,l,f,t,tl)
send(s,m,l,f)               ex. nbytes = send(s, msg, len, flags)
recvfrom(s,b,l,f,fr,frl)
recv(s,b,l,f)
shutdown(s,h)
setsockopt(s,l,o,ov,ol)
getsockopt(s,l,o,ov,ol)     ex. success =  getsockopt(s, level, optname, optval, optlen)
getsockname(s,h,n)
getpeername(s,h,n)
IoctlSocket(d,r,a)          ex. value = IoctlSocket(fd, request, arg)
CloseSocket(d)
WaitSelect(n,r,w,e,t,m)
SetSocketSignals(sin,sio,su)
getdtablesize()
ObtainSocket(i,d,t,p)
ReleaseSocket(f,i)
ReleaseCopyOfSocket(f,i)
Errno()
SetErrnoPtr(e,s)

d   domain
t   type
p   protocol
n   name
nl  namelen
l   level
r   request
a   arg
o   optname
ov  optval
ol  optlen
m   msg
l   length
f   flags

Inet_NtoA(i)
inet_addr(c)                ex. addr = inet_addr(cp)
Inet_LnaOf(i)
Inet_NetOf(i)
Inet_MakeAddr(n,h)
inet_network(c)
gethostbyname(n)
gethostbyaddr(a,l,t)
getnetbyname(n)
getnetbyaddr(n,t)
getservbyname(n,p)
getservbyport(p,pr)
getprotobyname(n)
getprotobynumber(p)
vsyslog(l,f,a)
Dup2Socket(fa,fb)
sendmsg(s,m,f)
recvmsg(s,m,f)
gethostname(h,s)
gethostid()
SocketBaseTagList(t)
GetSocketEvents(e)
getnetent(),                ex. struct netent *getnetent(void);
getprotoent(),              ex. struct protoent *getprotoent(void);
getservent(),               ex. struct servent *getservent(void);

the following tags are supported:

SBTC_BREAKMASK
SBTC_ERRNO
SBTC_HERRNO
SBTC_ERRNOSTRPTR
SBTC_HERRNOSTRPTR
SBTC_ERRNOBYTEPTR
SBTC_ERRNOWORDPTR
SBTC_ERRNOLONGPTR
SBTC_HERRNOLONGPTR
SBTC_SIGEVENTMASK

http://www.boogiejack.com/

<html>
<head>
<title>Welcome to my site</title>
<meta name="description" content="">
<meta name"keywords" content=" , ,">
</head>

<frameset rows = ....>
...etc...
</frameset>

<noframes>
<body>
<h1>You need to update your browser to one that supports frames!</h1>
You don't need a body at all unless you use the <noframes></noframes> tag. In all honesty you really should create a <noframes> section with nothing but navigation to the links of the rest of the page. There are still people out there who browse web sites without frames.
</body>
</noframes>
華夏公益教科書