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

📄 tclunixchan.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
    	status = 1;	(void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &status,		sizeof(status));	status = bind(sock, (struct sockaddr *) &sockaddr,                sizeof(struct sockaddr));	if (status != -1) {	    status = listen(sock, SOMAXCONN);	}     } else {	if (myaddr != NULL || myport != 0) { 	    curState = 1;	    (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,                    (char *) &curState, sizeof(curState));	    status = bind(sock, (struct sockaddr *) &mysockaddr,		    sizeof(struct sockaddr));	    if (status < 0) {		goto bindError;	    }	}	/*	 * Attempt to connect. The connect may fail at present with an	 * EINPROGRESS but at a later time it will complete. The caller	 * will set up a file handler on the socket if she is interested in	 * being informed when the connect completes.	 */        if (async) {#ifndef	USE_FIONBIO            origState = fcntl(sock, F_GETFL);            curState = origState | O_NONBLOCK;            status = fcntl(sock, F_SETFL, curState);#endif#ifdef	USE_FIONBIO            curState = 1;            status = ioctl(sock, FIONBIO, &curState);#endif                    } else {            status = 0;        }        if (status > -1) {            status = connect(sock, (struct sockaddr *) &sockaddr,                    sizeof(sockaddr));            if (status < 0) {                if (errno == EINPROGRESS) {                    asyncConnect = 1;                    status = 0;                }            }        }    }bindError:    if (status < 0) {        if (interp != NULL) {            Tcl_AppendResult(interp, "couldn't open socket: ",                    Tcl_PosixError(interp), (char *) NULL);        }        if (sock != -1) {            close(sock);        }        return NULL;    }    /*     * Allocate a new TcpState for this socket.     */    statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));    statePtr->flags = 0;    if (asyncConnect) {        statePtr->flags = TCP_ASYNC_CONNECT;    }    statePtr->fd = sock;        return statePtr;addressError:    if (sock != -1) {        close(sock);    }    if (interp != NULL) {	Tcl_AppendResult(interp, "couldn't open socket: ",		Tcl_PosixError(interp), (char *) NULL);    }    return NULL;}/* *---------------------------------------------------------------------- * * CreateSocketAddress -- * *	This function initializes a sockaddr structure for a host and port. * * Results: *	1 if the host was valid, 0 if the host could not be converted to *	an IP address. * * Side effects: *	Fills in the *sockaddrPtr structure. * *---------------------------------------------------------------------- */static intCreateSocketAddress(sockaddrPtr, host, port)    struct sockaddr_in *sockaddrPtr;	/* Socket address */    char *host;				/* Host.  NULL implies INADDR_ANY */    int port;				/* Port number */{    struct hostent *hostent;		/* Host database entry */    struct in_addr addr;		/* For 64/32 bit madness */    (void) memset((VOID *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));    sockaddrPtr->sin_family = AF_INET;    sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF));    if (host == NULL) {	addr.s_addr = INADDR_ANY;    } else {        addr.s_addr = inet_addr(host);        if (addr.s_addr == -1) {            hostent = gethostbyname(host);            if (hostent != NULL) {                memcpy((VOID *) &addr,                        (VOID *) hostent->h_addr_list[0],                        (size_t) hostent->h_length);            } else {#ifdef	EHOSTUNREACH                errno = EHOSTUNREACH;#else#ifdef ENXIO                errno = ENXIO;#endif#endif                return 0;	/* error */            }        }    }            /*     * NOTE: On 64 bit machines the assignment below is rumored to not     * do the right thing. Please report errors related to this if you     * observe incorrect behavior on 64 bit machines such as DEC Alphas.     * Should we modify this code to do an explicit memcpy?     */    sockaddrPtr->sin_addr.s_addr = addr.s_addr;    return 1;	/* Success. */}/* *---------------------------------------------------------------------- * * Tcl_OpenTcpClient -- * *	Opens a TCP client socket and creates a channel around it. * * Results: *	The channel or NULL if failed.  An error message is returned *	in the interpreter on failure. * * Side effects: *	Opens a client socket and creates a new channel. * *---------------------------------------------------------------------- */Tcl_ChannelTcl_OpenTcpClient(interp, port, host, myaddr, myport, async)    Tcl_Interp *interp;			/* For error reporting; can be NULL. */    int port;				/* Port number to open. */    char *host;				/* Host on which to open port. */    char *myaddr;			/* Client-side address */    int myport;				/* Client-side port */    int async;				/* If nonzero, attempt to do an                                         * asynchronous connect. Otherwise                                         * we do a blocking connect. */{    TcpState *statePtr;    char channelName[20];    /*     * Create a new client socket and wrap it in a channel.     */    statePtr = CreateSocket(interp, port, host, 0, myaddr, myport, async);    if (statePtr == NULL) {	return NULL;    }    statePtr->acceptProc = NULL;    statePtr->acceptProcData = (ClientData) NULL;    sprintf(channelName, "sock%d", statePtr->fd);    statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,            (ClientData) statePtr, (TCL_READABLE | TCL_WRITABLE));    if (Tcl_SetChannelOption(interp, statePtr->channel, "-translation",	    "auto crlf") == TCL_ERROR) {        Tcl_Close((Tcl_Interp *) NULL, statePtr->channel);        return NULL;    }    return statePtr->channel;}/* *---------------------------------------------------------------------- * * Tcl_MakeTcpClientChannel -- * *	Creates a Tcl_Channel from an existing client TCP socket. * * Results: *	The Tcl_Channel wrapped around the preexisting TCP socket. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_ChannelTcl_MakeTcpClientChannel(sock)    ClientData sock;		/* The socket to wrap up into a channel. */{    TcpState *statePtr;    char channelName[20];    statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));    statePtr->fd = (int) sock;    statePtr->acceptProc = NULL;    statePtr->acceptProcData = (ClientData) NULL;    sprintf(channelName, "sock%d", statePtr->fd);        statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,            (ClientData) statePtr, (TCL_READABLE | TCL_WRITABLE));    if (Tcl_SetChannelOption((Tcl_Interp *) NULL, statePtr->channel,	    "-translation", "auto crlf") == TCL_ERROR) {        Tcl_Close((Tcl_Interp *) NULL, statePtr->channel);        return NULL;    }    return statePtr->channel;}/* *---------------------------------------------------------------------- * * Tcl_OpenTcpServer -- * *	Opens a TCP server socket and creates a channel around it. * * Results: *	The channel or NULL if failed. If an error occurred, an *	error message is left in interp->result if interp is *	not NULL. * * Side effects: *	Opens a server socket and creates a new channel. * *---------------------------------------------------------------------- */Tcl_ChannelTcl_OpenTcpServer(interp, port, myHost, acceptProc, acceptProcData)    Tcl_Interp *interp;			/* For error reporting - may be                                         * NULL. */    int port;				/* Port number to open. */    char *myHost;			/* Name of local host. */    Tcl_TcpAcceptProc *acceptProc;	/* Callback for accepting connections                                         * from new clients. */    ClientData acceptProcData;		/* Data for the callback. */{    TcpState *statePtr;    char channelName[20];    /*     * Create a new client socket and wrap it in a channel.     */    statePtr = CreateSocket(interp, port, myHost, 1, NULL, 0, 0);    if (statePtr == NULL) {	return NULL;    }    statePtr->acceptProc = acceptProc;    statePtr->acceptProcData = acceptProcData;    /*     * Set up the callback mechanism for accepting connections     * from new clients.     */    Tcl_CreateFileHandler(statePtr->fd, TCL_READABLE, TcpAccept,            (ClientData) statePtr);    sprintf(channelName, "sock%d", statePtr->fd);    statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,            (ClientData) statePtr, 0);    return statePtr->channel;}/* *---------------------------------------------------------------------- * * TcpAccept -- *	Accept a TCP socket connection.  This is called by the event loop. * * Results: *	None. * * Side effects: *	Creates a new connection socket. Calls the registered callback *	for the connection acceptance mechanism. * *---------------------------------------------------------------------- */	/* ARGSUSED */static voidTcpAccept(data, mask)    ClientData data;			/* Callback token. */    int mask;				/* Not used. */{    TcpState *sockState;		/* Client data of server socket. */    int newsock;			/* The new client socket */    TcpState *newSockState;		/* State for new socket. */    struct sockaddr_in addr;		/* The remote address */    int len;				/* For accept interface */    char channelName[20];    sockState = (TcpState *) data;    len = sizeof(struct sockaddr_in);    newsock = accept(sockState->fd, (struct sockaddr *)&addr, &len);    if (newsock < 0) {        return;    }    /*     * Set close-on-exec flag to prevent the newly accepted socket from     * being inherited by child processes.     */    (void) fcntl(newsock, F_SETFD, FD_CLOEXEC);        newSockState = (TcpState *) ckalloc((unsigned) sizeof(TcpState));    newSockState->flags = 0;    newSockState->fd = newsock;    newSockState->acceptProc = (Tcl_TcpAcceptProc *) NULL;    newSockState->acceptProcData = (ClientData) NULL;            sprintf(channelName, "sock%d", newsock);    newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName,	    (ClientData) newSockState, (TCL_READABLE | TCL_WRITABLE));    Tcl_SetChannelOption((Tcl_Interp *) NULL, newSockState->channel,	    "-translation", "auto crlf");    if (sockState->acceptProc != (Tcl_TcpAcceptProc *) NULL) {	(sockState->acceptProc) (sockState->acceptProcData,		newSockState->channel, inet_ntoa(addr.sin_addr),		ntohs(addr.sin_port));    }}/* *---------------------------------------------------------------------- * * TclGetDefaultStdChannel -- * *	Creates channels for standard input, standard output or standard *	error output if they do not already exist. * * Results: *	Returns the specified default standard channel, or NULL. * * Side effects: *	May cause the creation of a standard channel and the underlying *	file. * *---------------------------------------------------------------------- */Tcl_ChannelTclGetDefaultStdChannel(type)    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */{    Tcl_Channel channel = NULL;    int fd = 0;			/* Initializations needed to prevent */    int mode = 0;		/* compiler warning (used before set). */    char *bufMode = NULL;    switch (type) {        case TCL_STDIN:            if ((lseek(0, (off_t) 0, SEEK_CUR) == -1) &&                    (errno == EBADF)) {                return (Tcl_Channel) NULL;            }	    fd = 0;	    mode = TCL_READABLE;            bufMode = "line";            break;        case TCL_STDOUT:            if ((lseek(1, (off_t) 0, SEEK_CUR) == -1) &&                    (errno == EBADF)) {                return (Tcl_Channel) NULL;            }	    fd = 1;	    mode = TCL_WRITABLE;            bufMode = "line";            break;        case TCL_STDERR:            if ((lseek(2, (off_t) 0, SEEK_CUR) == -1) &&                    (errno == EBADF)) {                return (Tcl_Channel) NULL;            }	    fd = 2;	    mode = TCL_WRITABLE;	    bufMode = "none";            break;	default:	    panic("TclGetDefaultStdChannel: Unexpected channel type");	    break;    }    channel = Tcl_MakeFileChannel((ClientData) fd, mode);    /*     * Set up the normal channel options for stdio handles.     */    Tcl_SetChannelOption(NULL, channel, "-translation", "auto");    Tcl_SetChannelOption(NULL, channel, "-buffering", bufMode);    return channel;}/* *---------------------------------------------------------------------- * * Tcl_GetOpenFile -- * *	Given a name of a channel registered in the given interpreter, *	returns a FILE * for it. * * Results: *	A standard Tcl result. If the channel is registered in the given *	interpreter and it is managed by the "file" channel driver, and *	it is open for the requested mode, then the output parameter *	filePtr is set to a FILE * for the underlying file. On error, the *	filePtr is not set, TCL_ERROR is returned and an error message is *	left in interp->result. * * Side effects: *	May invoke fdopen to create the FILE * for the requested file. * *---------------------------------------------------------------------- */intTcl_GetOpenFile(interp, string, forWriting, checkUsage, filePtr)    Tcl_Interp *interp;		/* Interpreter in which to find file. */    char *string;		/* String that identifies file. */    int forWriting;		/* 1 means the file is going to be used				 * for writing, 0 means for reading. */    int checkUsage;		/* 1 means verify that the file was opened

⌨️ 快捷键说明

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