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

📄 socket.c

📁 dtelent是开源的开发项目
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (rawGetProtocol() != protoNone && !local)
	/* Hve just switched from local flow control to remote flow
	 * control, initiate a read to catch any data that has been
	 * sent by remote end.
	 */
	readyForRead = TRUE;

    localFlowControl = local;
}

/* Stop or restart flow locally
 *
 * Args:
 * stop - should flow be stopped?
 */
void socketSetFlowStop(BOOL stop)
{
    if (stop == flowStopped)
	/* No change in value
	 */
	return;

    if (rawGetProtocol() != protoNone && localFlowControl && !stop)
	/* Have just restarted flow locally.  Initiate a read to catch
	 * any data that we have already received from the remote end
	 */
	readyForRead = TRUE;

    flowStopped = stop;
}

/* Return whether or not flow has been stopped locally
 */
BOOL socketFlowStopped(void)
{
    return flowStopped;
}

/* Display the current communications state in the status bar
 */
void socketShowStatus(void)
{
    switch (socketState) {
    case sockOffline:
	statusSetMsg("Offline");
	termSetTitle("Dave's Telnet - offline");
	break;
    case sockGetProxyHostName:
	statusSetMsg("Resolving Proxy server host name %s", proxyGetHost());
	break;
    case sockGetHostName:
	statusSetMsg("Resolving host name %s", socketHost);
	break;
    case sockGetServName:
	statusSetMsg("Resolving service name %s", socketService);
	break;
    case sockConnect:
        statusSetMsg("Connecting to %s/%d",
                proxyEnabled() ? inet_ntoa(proxyAddr.sin_addr) : inet_ntoa(addr.sin_addr),
                proxyEnabled() ? htons(proxyAddr.sin_port) : htons(addr.sin_port));
        break;
    case sockProxy:
	statusSetMsg("Sending Proxy request...");
	break;
    case sockOnline:
        statusSetMsg("Online to %s/%d",
                (proxyEnabled() && proxySupportHostname()) ? socketHost : inet_ntoa(addr.sin_addr),
                htons(addr.sin_port));
	break;
    }
}

/* Set and display the socket state
 */
static void socketSetState(SocketState state)
{
    socketState = state;
    socketShowStatus();
}

/* Window procedure for the socket window
 */
long CALLBACK socketWndProc(HWND wnd,
			    UINT message, WPARAM wparam, LPARAM lparam)
{                   
    WORD event;
    WORD error;
    int addrlen;

    event = WSAGETSELECTEVENT(lparam);
    error = WSAGETASYNCERROR(lparam);
    switch (message) {
    case WM_SOCK_GETHOSTBYNAME:
	/* Have just resolved the address of the remote end.  Save the
	 * data and then request the service port.  When the
	 * getservbyname operation finishes, windows sends the
	 * WM_SOCK_GETSERVBYNAME message back here.
	 */
	if (error) {
	    /* gethostbyname failed for some reason
	     */
	    socketError("WSAAsyncGetHostByName", error);
	    socketSetState(sockOffline);
	    break;
	}         
        if (socketState == sockGetProxyHostName) {
            /* if the selected proxy protocol don't support hostnames
             * as destination, resolve the host locally, otherwise
             * we request the service port.
             */
            socketSaveProxyHostname();
            if (!proxySupportHostname()) {
                socketGetHostByName();
            }
            else {
                socketGetServByName();
            }
        }
        else {
            socketSaveHostname();
            socketGetServByName();
        }
	break;

    case WM_SOCK_GETSERVBYNAME:
	/* Have just resolved the service port.  Save the data and
	 * then initiate a connection to the remote host.  When the
	 * connection completes, windows will send WM_SOCK_EVENT with
	 * FD_CONNECT as the event.
	 */
	if (error) {
	    socketError("WSAAsyncGetServByName", error);
	    socketSetState(sockOffline);
	    break;
	}
	socketSaveService();
	socketMakeNew();
	break;
		
    case WM_SOCK_EVENT:
	switch (event) {
	case FD_CLOSE:
	    /* Socket has been closed by the remote end.
	     */
	    remoteHasClosed = TRUE;
	    break;

	case FD_CONNECT:
	    /* Connect to remote end has completed
	     */
	    if (error) {
		closeSocket();
		socketError("connect()", error);
		break;
	    }
	    addrlen = sizeof (localAddr);
	    getsockname (sock, (struct sockaddr *)&localAddr, &addrlen);
	    strcpy (socketLocalIp, inet_ntoa (localAddr.sin_addr));
            if (proxyEnabled()) {
                int ret;
                char *dstHost;
                socketSetState(sockProxy);
                dstHost = proxySupportHostname() ? socketHost : inet_ntoa(addr.sin_addr);
                ret = proxyStartRequest(dstHost, ntohs(addr.sin_port));
                if (ret != PROXY_OK) {
                    closeSocket();
                    break;
                }
            }
            else {
                /* The connection was successful, set our state to online,
                 * update the application window title, kick start a new
                 * protocol session, and finally update the socket events
                 * we are interested in.
                 */
                socketSetState(sockOnline);
                telnetSetTitle();
                rawStartSession();
            }
            socketSelect();
	    break;

	case FD_READ:
	    /* There is some data ready to be read from the remote
	     * end.  Do not read the data now, the message loop will
	     * service the network IO once all GUI interaction is
	     * complete.
	     */
	    readyForRead = TRUE;
	    break;

	case FD_WRITE:
	    /* The socket is ready for us to send some more data to
	     * the remote end.  Handle this as per FD_READ
	     */
	    readyForWrite = TRUE;
	    break;

	case FD_OOB:
	    /* Received some urgent data from remote end.  Probably
	     * result of pressing ^C.
	     */
	    socketOobReady();
	    break;
	}
	break;

    case WM_DESTROY:
	/* Our window has been destroyed, close up the socket
	 */
	closeSocket();
	return 0;

    default:
	return DefWindowProc(wnd, message, wparam, lparam);
    }
    return 0;
}

/* Return the remote host passed into socketConnect()
 */
char* socketGetHost()
{
    return socketHost;
}

/* Return the remote service passed into socketConnect()
 */
char* socketGetPort()
{
    return socketService;
}

/* Return the handle of the socket
 */
SOCKET socketGetHandle(void)
{
    return sock;
}

/* Return local IP-address as a string
 */
char *socketGetLocalIP()
{
    return socketLocalIp;
}

/* Initiate a connection to the remote end.
 *
 * Args:
 * host -    the hostname or IP address (as string) to connect to
 * service - te service name or port number (as string) to connect to
 */
void socketConnect(const char* host, const char* service)
{
    /* Store the session details for later reference
     */
    strcpy(socketHost, host);
    strcpy(socketService, service);

    if (proxyEnabled()) {
        /* if proxy is enabled, we resolve first the proxy server host name
         */
        socketGetProxyHostByName();
    }
    else {
        /* We start the ball rolling by finding the address of the remote
         * end.  When the gethostbyname operation finishes, windows sends
         * the WM_SOCK_GETHOSTBYNAME message back here.
         */
        socketGetHostByName();
    }
}

/* Queue some data to be written to the remote end.
 *
 * Args:
 * text - the data to be sent to the remote end
 * len -  the amount of data to be sent
 */
void socketWrite(const char* text, int len)
{
    Data* data;			/* queue entry for data */
    BOOL wasEmpty = dataQueue == NULL; /* was the queue empty when function called */

    ASSERT(text != NULL);
    ASSERT(len > 0);
    ASSERT(len < INT_MAX);
    if (socketState != sockOnline)
	/* Do not queue data if we are not connected
	 */
	return;

    /* Allocate a queue entry and get a local copy of the data to be
     * queued
     */
    data = (Data *)xmalloc(sizeof(*data));
    ASSERT(data != NULL);
    memset(data, 0, sizeof(*data));
    data->text = (unsigned char *)xmalloc(len);
    ASSERT(data->text != NULL);
    data->len = len;
    memcpy(data->text, text, len);

    /* Add the data to the end of the queue
     */
    if (dataEnd != NULL)
	dataEnd->next = data;
    else
	dataQueue = data;
    dataEnd = data;

    /* If there is already data in the queue, just queue the data.  If
     * this is the only data, and the socket is ready for writing then
     * try to write this data.
     */
    if (wasEmpty)
	socketWriteReady();
}

/* Check for a local X-server */
BOOL socketHaveXServer ()
{
    SOCKET s;
    struct sockaddr_in sa;
    int rc;
    DWORD err;
    static BOOL fTested= FALSE, fHave= FALSE;

/*  if (fTested) return fHave; *//* optimization? */

    s = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s==(SOCKET)-1) {
	fHave = FALSE;
	fTested = TRUE;
	return fHave;
    }

    memset (&sa, 0, sizeof (sa));
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr  = INADDR_ANY;
    sa.sin_port = htons (6000); /* X-server' port */
    rc = bind (s, (struct sockaddr *)&sa, sizeof (sa));
    if (rc==-1) {
	err = WSAGetLastError ();
	if (err == WSAEADDRINUSE) fHave = TRUE;
    }
    closesocket (s);
    fTested = TRUE;
    return fHave;
}

/* Register the window class that will receive the socket messages
 */
BOOL socketInitClass(HINSTANCE instance)
{
    WNDCLASS wc;

    wc.style = 0;
    wc.lpfnWndProc = socketWndProc;
    wc.cbClsExtra = wc.cbWndExtra = 0;
    wc.hInstance = instance;
    wc.hIcon = NULL;
    wc.hCursor = 0;
    wc.hbrBackground = 0;
    wc.lpszMenuName =  NULL;
    wc.lpszClassName = socketWinClass;
    return RegisterClass(&wc);
}

/* Initialise WINSOCK
 */
BOOL socketInit(HINSTANCE instance)
{
    int ret;

    if ((ret = WSAStartup(SOCKLIB_VERSION, &WSAData))!=0) {
	socketError("WSAStartup()", ret);
	return FALSE;
    }                
    sockWnd = CreateWindow(socketWinClass, "", 0,
			   0, 0, 0, 0,
			   NULL, NULL, instance, NULL);
    if (!sockWnd) {
	if (WSACleanup())
	    socketError("WSACleanup()", WSAGetLastError());
	return FALSE;
    }
    return TRUE;
}

/* Unregister with WINSOCK
 */
void socketCleanup()
{
    if (WSAIsBlocking())
	if (WSACancelBlockingCall())
	    ;
    if (WSACleanup())
	;
}

⌨️ 快捷键说明

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