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

📄 tclwinsock.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * tclWinSock.c -- * *	This file contains Windows-specific socket related code. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclWinSock.c 1.80 97/10/09 18:24:59 */#include "tclInt.h"#include "tclPort.h"/* * The following variable is used to tell whether this module has been * initialized. */static int initialized = 0;static int  hostnameInitialized = 0;static char hostname[255];	/* This buffer should be big enough for                                 * hostname plus domain name. *//* * The following structure contains pointers to all of the WinSock API entry * points used by Tcl.  It is initialized by InitSockets.  Since we * dynamically load Winsock.dll on demand, we must use this function table * to refer to functions in the socket API. */static struct {    HINSTANCE hInstance;	/* Handle to WinSock library. */    HWND hwnd;			/* Handle to window for socket messages. */    SOCKET (PASCAL FAR *accept)(SOCKET s, struct sockaddr FAR *addr,	    int FAR *addrlen);    int (PASCAL FAR *bind)(SOCKET s, const struct sockaddr FAR *addr,	    int namelen);    int (PASCAL FAR *closesocket)(SOCKET s);    int (PASCAL FAR *connect)(SOCKET s, const struct sockaddr FAR *name,	    int namelen);    int (PASCAL FAR *ioctlsocket)(SOCKET s, long cmd, u_long FAR *argp);    int (PASCAL FAR *getsockopt)(SOCKET s, int level, int optname,	    char FAR * optval, int FAR *optlen);    u_short (PASCAL FAR *htons)(u_short hostshort);    unsigned long (PASCAL FAR *inet_addr)(const char FAR * cp);    char FAR * (PASCAL FAR *inet_ntoa)(struct in_addr in);    int (PASCAL FAR *listen)(SOCKET s, int backlog);    u_short (PASCAL FAR *ntohs)(u_short netshort);    int (PASCAL FAR *recv)(SOCKET s, char FAR * buf, int len, int flags);    int (PASCAL FAR *select)(int nfds, fd_set FAR * readfds,	    fd_set FAR * writefds, fd_set FAR * exceptfds,	    const struct timeval FAR * tiemout);    int (PASCAL FAR *send)(SOCKET s, const char FAR * buf, int len, int flags);    int (PASCAL FAR *setsockopt)(SOCKET s, int level, int optname,	    const char FAR * optval, int optlen);    int (PASCAL FAR *shutdown)(SOCKET s, int how);    SOCKET (PASCAL FAR *socket)(int af, int type, int protocol);    struct hostent FAR * (PASCAL FAR *gethostbyname)(const char FAR * name);    struct hostent FAR * (PASCAL FAR *gethostbyaddr)(const char FAR *addr,            int addrlen, int addrtype);    int (PASCAL FAR *gethostname)(char FAR * name, int namelen);    int (PASCAL FAR *getpeername)(SOCKET sock, struct sockaddr FAR *name,            int FAR *namelen);    struct servent FAR * (PASCAL FAR *getservbyname)(const char FAR * name,	    const char FAR * proto);    int (PASCAL FAR *getsockname)(SOCKET sock, struct sockaddr FAR *name,            int FAR *namelen);    int (PASCAL FAR *WSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData);    int (PASCAL FAR *WSACleanup)(void);    int (PASCAL FAR *WSAGetLastError)(void);    int (PASCAL FAR *WSAAsyncSelect)(SOCKET s, HWND hWnd, u_int wMsg,	    long lEvent);} winSock;/* * The following defines declare the messages used on socket windows. */#define SOCKET_MESSAGE	WM_USER+1/* * The following structure is used to store the data associated with * each socket. */typedef struct SocketInfo {    Tcl_Channel channel;	   /* Channel associated with this socket. */    SOCKET socket;		   /* Windows SOCKET handle. */    int flags;			   /* Bit field comprised of the flags				    * described below.  */    int watchEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that				    * indicate which events are interesting. */    int readyEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that				    * indicate which events have occurred. */    int selectEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that				    * indicate which events are currently				    * being selected. */    Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */    ClientData acceptProcData;	   /* The data for the accept proc. */    int lastError;		   /* Error code from last message. */    struct SocketInfo *nextPtr;	   /* The next socket on the global socket				    * list. */} SocketInfo;/* * The following structure is what is added to the Tcl event queue when * a socket event occurs. */typedef struct SocketEvent {    Tcl_Event header;		/* Information that is standard for				 * all events. */    SOCKET socket;		/* Socket descriptor that is ready.  Used				 * to find the SocketInfo structure for				 * the file (can't point directly to the				 * SocketInfo structure because it could				 * go away while the event is queued). */} SocketEvent;/* * This defines the minimum buffersize maintained by the kernel. */#define TCP_BUFFER_SIZE 4096/* * The following macros may be used to set the flags field of * a SocketInfo structure. */#define SOCKET_ASYNC		(1<<0)	/* The socket is in blocking mode. */#define SOCKET_EOF		(1<<1)	/* A zero read happened on					 * the socket. */#define SOCKET_ASYNC_CONNECT	(1<<2)	/* This socket uses async connect. */#define SOCKET_PENDING		(1<<3)	/* A message has been sent					 * for this socket *//* * Every open socket has an entry on the following list. */static SocketInfo *socketList;/* * Static functions defined in this file. */static SocketInfo *	CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,			    int port, char *host, int server, char *myaddr,			    int myport, int async));static int		CreateSocketAddress _ANSI_ARGS_(			    (struct sockaddr_in *sockaddrPtr,			    char *host, int port));static void		InitSockets _ANSI_ARGS_((void));static SocketInfo *	NewSocketInfo _ANSI_ARGS_((SOCKET socket));static void		SocketCheckProc _ANSI_ARGS_((ClientData clientData,			    int flags));static int		SocketEventProc _ANSI_ARGS_((Tcl_Event *evPtr,			    int flags));static void		SocketExitHandler _ANSI_ARGS_((ClientData clientData));static LRESULT CALLBACK	SocketProc _ANSI_ARGS_((HWND hwnd, UINT message,			    WPARAM wParam, LPARAM lParam));static void		SocketSetupProc _ANSI_ARGS_((ClientData clientData,			    int flags));static void		TcpAccept _ANSI_ARGS_((SocketInfo *infoPtr));static int		TcpBlockProc _ANSI_ARGS_((ClientData instanceData,			    int mode));static int		TcpCloseProc _ANSI_ARGS_((ClientData instanceData,	            	    Tcl_Interp *interp));static int		TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData,		            Tcl_Interp *interp, char *optionName,			    Tcl_DString *optionValue));static int		TcpInputProc _ANSI_ARGS_((ClientData instanceData,	            	    char *buf, int toRead, int *errorCode));static int		TcpOutputProc _ANSI_ARGS_((ClientData instanceData,	            	    char *buf, int toWrite, int *errorCode));static void		TcpWatchProc _ANSI_ARGS_((ClientData instanceData,		            int mask));static int		TcpGetHandleProc _ANSI_ARGS_((ClientData instanceData,		            int direction, ClientData *handlePtr));static int		WaitForSocketEvent _ANSI_ARGS_((SocketInfo *infoPtr,		            int events, int *errorCodePtr));/* * This structure describes the channel type structure for TCP socket * based IO. */static Tcl_ChannelType tcpChannelType = {    "tcp",		/* Type name. */    TcpBlockProc,	/* Set socket into blocking/non-blocking mode. */    TcpCloseProc,	/* Close proc. */    TcpInputProc,	/* Input proc. */    TcpOutputProc,	/* Output proc. */    NULL,		/* Seek proc. */    NULL,		/* Set option proc. */    TcpGetOptionProc,	/* Get option proc. */    TcpWatchProc,	/* Initialize notifier to watch this channel. */    TcpGetHandleProc,	/* Get an OS handle from channel. */};/* * Define version of Winsock required by Tcl. */#define WSA_VERSION_REQD MAKEWORD(1,1)/* *---------------------------------------------------------------------- * * InitSockets -- * *	Initialize the socket module.  Attempts to load the wsock32.dll *	library and set up the winSock function table.  If successful, *	registers the event window for the socket notifier code. * * Results: *	None. * * Side effects: *	Dynamically loads wsock32.dll, and registers a new window *	class and creates a window for use in asynchronous socket *	notification. * *---------------------------------------------------------------------- */static voidInitSockets(){    WSADATA wsaData;    OSVERSIONINFO info;    WNDCLASS class;    initialized = 1;    Tcl_CreateExitHandler(SocketExitHandler, (ClientData) NULL);    /*     * Find out if we're running on Win32s.     */    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);    GetVersionEx(&info);    /*     * Check to see if Sockets are supported on this system.  Since     * win32s panics if we call WSAStartup on a system that doesn't     * have winsock.dll, we need to look for it on the system first.     * If we find winsock, then load the library and initialize the     * stub table.     */    if ((info.dwPlatformId != VER_PLATFORM_WIN32s)	    || (SearchPath(NULL, "WINSOCK", ".DLL", 0, NULL, NULL) != 0)) {	winSock.hInstance = LoadLibrary("wsock32.dll");    } else {	winSock.hInstance = NULL;    }    /*     * Initialize the function table.     */    if (winSock.hInstance == NULL) {	return;    }    winSock.accept = (SOCKET (PASCAL FAR *)(SOCKET s,            struct sockaddr FAR *addr, int FAR *addrlen))        GetProcAddress(winSock.hInstance, "accept");    winSock.bind = (int (PASCAL FAR *)(SOCKET s,            const struct sockaddr FAR *addr, int namelen))        GetProcAddress(winSock.hInstance, "bind");    winSock.closesocket = (int (PASCAL FAR *)(SOCKET s))        GetProcAddress(winSock.hInstance, "closesocket");    winSock.connect = (int (PASCAL FAR *)(SOCKET s,            const struct sockaddr FAR *name, int namelen))        GetProcAddress(winSock.hInstance, "connect");    winSock.ioctlsocket = (int (PASCAL FAR *)(SOCKET s, long cmd,            u_long FAR *argp)) GetProcAddress(winSock.hInstance, "ioctlsocket");    winSock.getsockopt = (int (PASCAL FAR *)(SOCKET s,            int level, int optname, char FAR * optval, int FAR *optlen))        GetProcAddress(winSock.hInstance, "getsockopt");    winSock.htons = (u_short (PASCAL FAR *)(u_short hostshort))        GetProcAddress(winSock.hInstance, "htons");    winSock.inet_addr = (unsigned long (PASCAL FAR *)(const char FAR *cp))        GetProcAddress(winSock.hInstance, "inet_addr");    winSock.inet_ntoa = (char FAR * (PASCAL FAR *)(struct in_addr in))        GetProcAddress(winSock.hInstance, "inet_ntoa");    winSock.listen = (int (PASCAL FAR *)(SOCKET s, int backlog))        GetProcAddress(winSock.hInstance, "listen");    winSock.ntohs = (u_short (PASCAL FAR *)(u_short netshort))        GetProcAddress(winSock.hInstance, "ntohs");    winSock.recv = (int (PASCAL FAR *)(SOCKET s, char FAR * buf,            int len, int flags)) GetProcAddress(winSock.hInstance, "recv");    winSock.select = (int (PASCAL FAR *)(int nfds, fd_set FAR * readfds,	    fd_set FAR * writefds, fd_set FAR * exceptfds,	    const struct timeval FAR * tiemout))	GetProcAddress(winSock.hInstance, "select");    winSock.send = (int (PASCAL FAR *)(SOCKET s, const char FAR * buf,            int len, int flags)) GetProcAddress(winSock.hInstance, "send");    winSock.setsockopt = (int (PASCAL FAR *)(SOCKET s, int level,            int optname, const char FAR * optval, int optlen))        GetProcAddress(winSock.hInstance, "setsockopt");    winSock.shutdown = (int (PASCAL FAR *)(SOCKET s, int how))        GetProcAddress(winSock.hInstance, "shutdown");    winSock.socket = (SOCKET (PASCAL FAR *)(int af, int type,            int protocol)) GetProcAddress(winSock.hInstance, "socket");    winSock.gethostbyaddr = (struct hostent FAR * (PASCAL FAR *)            (const char FAR *addr, int addrlen, int addrtype))        GetProcAddress(winSock.hInstance, "gethostbyaddr");    winSock.gethostbyname = (struct hostent FAR * (PASCAL FAR *)            (const char FAR *name))        GetProcAddress(winSock.hInstance, "gethostbyname");    winSock.gethostname = (int (PASCAL FAR *)(char FAR * name,            int namelen)) GetProcAddress(winSock.hInstance, "gethostname");    winSock.getpeername = (int (PASCAL FAR *)(SOCKET sock,            struct sockaddr FAR *name, int FAR *namelen))        GetProcAddress(winSock.hInstance, "getpeername");    winSock.getservbyname = (struct servent FAR * (PASCAL FAR *)            (const char FAR * name, const char FAR * proto))        GetProcAddress(winSock.hInstance, "getservbyname");    winSock.getsockname = (int (PASCAL FAR *)(SOCKET sock,            struct sockaddr FAR *name, int FAR *namelen))        GetProcAddress(winSock.hInstance, "getsockname");    winSock.WSAStartup = (int (PASCAL FAR *)(WORD wVersionRequired,            LPWSADATA lpWSAData)) GetProcAddress(winSock.hInstance, "WSAStartup");    winSock.WSACleanup = (int (PASCAL FAR *)(void))        GetProcAddress(winSock.hInstance, "WSACleanup");    winSock.WSAGetLastError = (int (PASCAL FAR *)(void))        GetProcAddress(winSock.hInstance, "WSAGetLastError");    winSock.WSAAsyncSelect = (int (PASCAL FAR *)(SOCKET s, HWND hWnd,            u_int wMsg, long lEvent))        GetProcAddress(winSock.hInstance, "WSAAsyncSelect");    /*     * Now check that all fields are properly initialized. If not, return     * zero to indicate that we failed to initialize properly.     */    if ((winSock.hInstance == NULL) ||            (winSock.accept == NULL) ||            (winSock.bind == NULL) ||            (winSock.closesocket == NULL) ||            (winSock.connect == NULL) ||            (winSock.ioctlsocket == NULL) ||            (winSock.getsockopt == NULL) ||            (winSock.htons == NULL) ||            (winSock.inet_addr == NULL) ||            (winSock.inet_ntoa == NULL) ||            (winSock.listen == NULL) ||            (winSock.ntohs == NULL) ||            (winSock.recv == NULL) ||            (winSock.select == NULL) ||            (winSock.send == NULL) ||            (winSock.setsockopt == NULL) ||            (winSock.socket == NULL) ||            (winSock.gethostbyname == NULL) ||            (winSock.gethostbyaddr == NULL) ||            (winSock.gethostname == NULL) ||            (winSock.getpeername == NULL) ||            (winSock.getservbyname == NULL) ||            (winSock.getsockname == NULL) ||            (winSock.WSAStartup == NULL) ||            (winSock.WSACleanup == NULL) ||            (winSock.WSAGetLastError == NULL) ||            (winSock.WSAAsyncSelect == NULL)) {	goto unloadLibrary;    }        /*     * Initialize the winsock library and check the version number.     */    if ((*winSock.WSAStartup)(WSA_VERSION_REQD, &wsaData) != 0) {	goto unloadLibrary;    }    if (wsaData.wVersion != WSA_VERSION_REQD) {	(*winSock.WSACleanup)();	goto unloadLibrary;    }    /*     * Create the async notification window with a new class.  We     * must create a new class to avoid a Windows 95 bug that causes     * us to get the wrong message number for socket events if the     * message window is a subclass of a static control.     */    class.style = 0;    class.cbClsExtra = 0;    class.cbWndExtra = 0;    class.hInstance = TclWinGetTclInstance();    class.hbrBackground = NULL;    class.lpszMenuName = NULL;    class.lpszClassName = "TclSocket";    class.lpfnWndProc = SocketProc;    class.hIcon = NULL;    class.hCursor = NULL;    if (RegisterClass(&class)) {	winSock.hwnd = CreateWindow("TclSocket", "TclSocket", WS_TILED, 0, 0,		0, 0, NULL, NULL, class.hInstance, NULL);    } else {	winSock.hwnd = NULL;    }    if (winSock.hwnd == NULL) {	TclWinConvertError(GetLastError());	(*winSock.WSACleanup)();	goto unloadLibrary;    }    Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);    return;unloadLibrary:    FreeLibrary(winSock.hInstance);    winSock.hInstance = NULL;    return;

⌨️ 快捷键说明

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