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

📄 socket.c

📁 xmlrpc,用 XML表示得远程过程调用,基于web上得远程计算
💻 C
字号:
/*******************************************************************************
**
** socket.c
**
** This file is part of the ABYSS Web server project.
**
** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
**    notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
**    notice, this list of conditions and the following disclaimer in the
**    documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
**    derived from this software without specific prior written permission.
** 
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
**
*******************************************************************************/

#include "abyss.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef ABYSS_WIN32
#define  EINTR		WSAEINTR
#endif

static abyss_bool ABYSS_TRACE_SOCKET;

/*********************************************************************
** Socket
*********************************************************************/

abyss_bool SocketInit()
{
    abyss_bool retval;
#ifdef ABYSS_WIN32
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
 
	wVersionRequested = MAKEWORD( 2, 0 );
 
	err = WSAStartup( wVersionRequested, &wsaData );
	retval = ( err == 0 );
#else
	retval = TRUE;
    ABYSS_TRACE_SOCKET = (getenv("ABYSS_TRACE_SOCKET") != NULL);
#endif	/* ABYSS_WIN32 */
    if (ABYSS_TRACE_SOCKET)
        fprintf(stderr, "Abyss socket layer will trace socket traffic "
                "due to ABYSS_TRACE_SOCKET environment variable\n");
    return retval;
}

#define RET(x)	return ((x)!=(-1))

abyss_bool SocketCreate(TSocket *s)
{
    int rc;

    rc =socket(AF_INET,SOCK_STREAM,0);
    if (rc < 0)
		return FALSE;
    else {
        int32 n=1;
        *s = rc;
        RET(setsockopt(*s,SOL_SOCKET,SO_REUSEADDR,(char*)&n,sizeof(n)));
    }
}

abyss_bool SocketClose(TSocket *s)
{
#ifdef ABYSS_WIN32
	RET(closesocket(*s));
#else
	RET(close(*s));
#endif	/* ABYSS_WIN32 */
}

uint32 SocketWrite(TSocket *s, char *buffer, uint32 len)
{
	return send(*s,buffer,len,0);
}



uint32 SocketRead(TSocket * const socketP, 
                  char *    const buffer, 
                  uint32    const len) {
    int rc;
    rc = recv(*socketP, buffer, len, 0);
    if (ABYSS_TRACE_SOCKET) {
        if (rc < 0)
            fprintf(stderr, "Abyss socket: recv() failed.  errno=%d (%s)",
                    errno, strerror(errno));
        else 
            fprintf(stderr, "Abyss socket: read %u bytes: '%.*s'\n",
                    len, (int)len, buffer);
    }
    return rc;
}



uint32 SocketPeek(TSocket *s, char *buffer, uint32 len)
{
	int32 r=recv(*s,buffer,len,MSG_PEEK);

	if (r==(-1))
#ifdef ABYSS_WIN32
		if (SocketError()==WSAEMSGSIZE)
#else
		if (SocketError()==EMSGSIZE)
#endif
			return len;

	return r;
}

abyss_bool SocketConnect(TSocket *s, TIPAddr *addr, uint16 port)
{
	struct sockaddr_in name;

	name.sin_family=AF_INET;
	name.sin_port=htons(port);
	name.sin_addr=*addr;

	RET(connect(*s,(struct sockaddr *)&name,sizeof(name)));
}

abyss_bool SocketBind(TSocket *s, TIPAddr *addr, uint16 port)
{
	struct sockaddr_in name;

	name.sin_family=AF_INET;
	name.sin_port=htons(port);
	if (addr)
		name.sin_addr=*addr;
	else
		name.sin_addr.s_addr=INADDR_ANY;

	RET(bind(*s,(struct sockaddr *)&name,sizeof(name)));
}

abyss_bool SocketListen(TSocket *s, uint32 backlog)
{
	int32 n=-1;

	/* Disable the naggle algorithm to make persistant connections faster */
	setsockopt(*s, IPPROTO_TCP,TCP_NODELAY,(char *)&n,sizeof(n));

	RET(listen(*s,backlog));
}

abyss_bool SocketAccept(TSocket *s, TSocket *ns,TIPAddr *ip)
{
	struct sockaddr_in sa;
	uint32 size=sizeof(sa);
    abyss_bool connected;

    connected = FALSE;
	for (;;) {
        int rc;
        rc = accept(*s,(struct sockaddr *)&sa,&size);
        if (rc >= 0)
		{
            connected = TRUE;
            *ns = rc;
			*ip=sa.sin_addr;
			break;
		}
		else
			if (SocketError()!=EINTR)
				break;
    }	
	return connected;
}

uint32 SocketWait(TSocket *s,abyss_bool rd,abyss_bool wr,uint32 timems)
{
	fd_set rfds,wfds;
#ifdef ABYSS_WIN32
	TIMEVAL tv;
#else
	struct timeval tv;
#endif	/* ABYSS_WIN32 */

	FD_ZERO(&rfds);
	FD_ZERO(&wfds);

	if (rd)
		FD_SET(*s,&rfds);

	if (wr)
		FD_SET(*s,&wfds);

	tv.tv_sec=timems/1000;
	tv.tv_usec=timems%1000;


	for (;;)
		switch(select((*s)+1,&rfds,&wfds,NULL,
			(timems==TIME_INFINITE?NULL:&tv)))
		{ 	
		case 0:	/* time out */
			return 0;

		case (-1):	/* socket error */
			if (SocketError()==EINTR)
				break;
			
			return 0;

		default:
			if (FD_ISSET(*s,&rfds))
				return 1;
			if (FD_ISSET(*s,&wfds))
				return 2;
			return 0;
		};
}

abyss_bool SocketBlocking(TSocket *s, abyss_bool b)
{
	uint32 x=b;

	RET(ioctlsocket(*s,FIONBIO,&x));
}

uint32 SocketAvailableReadBytes(TSocket *s)
{
	uint32 x;

	if (ioctlsocket(*s,FIONREAD,&x)!=0)
		x=0;

	return x;
}

uint32 SocketError()
{
#ifdef ABYSS_WIN32
	return WSAGetLastError();
#else
	return errno;
#endif	/* ABYSS_WIN32 */
}

⌨️ 快捷键说明

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