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

📄 tcp_socket.c

📁 unix下多进程编程实例
💻 C
📖 第 1 页 / 共 2 页
字号:
	if(rc < 0){		/* recv error */
		ErrorLog(COMMERR_TYPE,"SYSTEM","检查接收到的通信包时出错");
		return -1;
	}else if(rc != sizeof(PacketHead)){	/* received size error */
		for(iLoop=0;iLoop<20;iLoop++){
			rc = recv( sd, &stHead, sizeof(PacketHead), MSG_PEEK );
			if(rc < 0){
				ErrorLog(COMMERR_TYPE,"SYSTEM","检查接收到的通信包时出错");
				return -1;
			}else if(rc != sizeof(PacketHead)){
				continue;
			}else{
				break;
			}
		}
	}

	/* 检查是否仍然没收全 */
	if(rc != sizeof(PacketHead)){	/* 经过重试,收到的包依然不全 */
		DebugLog("Real received = %d,want receive = %d",rc,sizeof(PacketHead));
		ErrorLog(COMMERR_TYPE,"SYSTEM","检查接收到的通信包时出错");
		return -1;
	}

	/* 检查包的大小,不大于100M */
	if(stHead.lPacketSize > 100*1024*1024 || stHead.lPacketSize< sizeof(PacketHead)){
		ErrorLog(COMMERR_TYPE,"SYSTEM","收到的数据包过大。");
		ioctl(sd,I_FLUSH,FLUSHR);
		return -1;
	}
	/* 系统认证 */
	if(strcmp(stHead.sSystemID,SYSTEM_ID)){
		ErrorLog(COMMERR_TYPE,"SYSTEM","收到的数据包不属于本系统。");
		ioctl(sd,I_FLUSH,FLUSHR);
		return -1;
	}

    return stHead.lPacketSize;
}


/********************************************************************
 * NAME     : TCP_Recv
 * FUNCTION : recieve data by socket
 * PROCESS  : 1. receive all data in socket
 *          : 2. pack these data into a buffer
 * INPUT    : sd       : socket ID
 *          : pBuffer  : buffer used in store received data
 *          : lSize    : received size expected 
 *          : nTimeOut : time out ( seconds )
 * OUTPUT   : 
 * UPDATE   :
 * RETURN   : -1    : fail
 *          : other : received data real size
 * AUTHOR	: ZZ-NODE/2000.12.18/songqufei
 * CALL     : select()
 *          : recv()
 *          : ioctl()
 *          : FD_SET()
 ********************************************************************/
int TCP_Recv(int sd,char *pBuffer,int lSize,int nTimeOut  )
{
	int	iEachMaxSiz = 4096;		/* each received max size  */
	int	iEachRealSiz = 0;		/* each need receive  size  */
    int iTotalRecv = 0;			/* the total received bytes */
	int	iLeftSiz;				/* the left size */
    int	iSele,iRecv;			/* select return value, the received real size */
    
    fd_set    rd_set;
    struct timeval    tv;
    
    tv.tv_sec = nTimeOut;
    tv.tv_usec = 0;

	iLeftSiz = lSize;
	while(1){
		if(iLeftSiz<=0)	break;	/* 已经全部收完 */

		FD_ZERO(&rd_set);
		FD_SET(sd, &rd_set);
		iSele = (int) select(sd+1, &rd_set, NULL, NULL, &tv);
		if(iSele < 0) {
			DebugLog("接收数据包select出错。");
			ErrorLog(COMMERR_TYPE,"SYSTEM","接收数据包select出错。");
			return( -1 );
		}else if(iSele == 0) {
			DebugLog("接收数据包select超时");
			return (-1);
		}
		
		iEachRealSiz = iLeftSiz>iEachMaxSiz? iEachMaxSiz: iLeftSiz;
		iRecv = recv(sd,pBuffer,iEachRealSiz,0);
		if(iRecv < 0) {
			DebugLog("接收数据包recv出错。");
			ErrorLog(COMMERR_TYPE,"SYSTEM","接收数据包recv出错。");
			return( -1 );         
		}else if(iRecv == 0){
			break;	/* 没有收到想要收的东西,返回已经收到的内容 */
		}

		pBuffer += iRecv;		/* 修改buf指针 */
		iLeftSiz -= iRecv;		/* 重新计算剩余字节数 */
		iTotalRecv += iRecv;	/* 计算收到字节总数 */
	}

    return ( iTotalRecv );
}



/********************************************************************
 * NAME     : TCP_Close
 * FUNCTION : close socket
 * PROCESS  : 1. disable both send & receive
 *          : 2. close socket
 * INPUT    : sd : socket ID
 * OUTPUT   : 
 * UPDATE   :
 * RETURN   : 
 * AUTHOR	: ZZ-NODE/2000.12.18/songqufei
 * CALL     : close()
 *          : shutdown()
 ********************************************************************/
int TCP_Close(int sd )
{
	sleep(2);
    shutdown( sd, 2 );    /* disable both send & recv    */
	sleep(2);
    close( sd );
	sleep(2);
    return 0;
}


/********************************************************************
 * NAME     : Send_PacketHead
 * FUNCTION : 向指定端口传送特殊的包头
 * PROCESS  : 
 * INPUT    : sd        : 端口ID
 *          : iPacketID : 包ID
 * OUTPUT   : 
 * UPDATE   : 
 * RETURN   : IS_OK  : ok
 *			: IS_NG  : fail
 * AUTHOR	: ZZ-NODE/2000.12.21/songqufei
 * CALL     : 
 ********************************************************************/
int Send_PacketHead(int sd,int iPacketID)
{
	PacketHead stPacketHead;
	
	memset(&stPacketHead,0,sizeof(PacketHead));

	stPacketHead.iPacketID = iPacketID;
	stPacketHead.lPacketSize = sizeof(PacketHead);
	stPacketHead.iRecordNum  = 1;
	
	if(TCP_SendPacket(sd,&stPacketHead)<0) {
		ErrorLog(ERROR_SOCKET_WRITE,"SYSTEM","send packet error");
		return IS_NG;
	};

	return IS_OK;
}


/********************************************************************
 * NAME     : Return_PacketHead
 * FUNCTION : 向指定端口返回特殊的包头
 * PROCESS  : 
 * INPUT    : sd           : 端口ID
 *          : iRetPacketID : 包ID
 * OUTPUT   : 
 * UPDATE   : 
 * RETURN   : IS_OK  : ok
 *			: IS_NG  : fail
 * AUTHOR	: ZZ-NODE/2000.12.21/songqufei
 * CALL     : 
 ********************************************************************/
int Return_PacketHead(int sd,int iRetPacketID,char cRetCode)
{
	PacketHead stPacketHead;
	
	memset(&stPacketHead,0,sizeof(PacketHead));

	stPacketHead.iPacketID = P_COM_SV_RET;
	stPacketHead.iRetPktID = iRetPacketID;
	stPacketHead.lPacketSize = sizeof(PacketHead);
	stPacketHead.iRecordNum  = 0;
	stPacketHead.cRetCode  = cRetCode;
	
	if(TCP_SendPacket(sd,&stPacketHead)<0) {
		ErrorLog(ERROR_SOCKET_WRITE,"SYSTEM","send packet error");
		return IS_NG;
	};

	return IS_OK;
}


/********************************************************************
 * NAME     : TCP_EstablishConnection
 * FUNCTION : client connect to server
 * PROCESS  : 1. get host by name
 *          : 2. get service by name
 *          : 3. creat socket
 *          : 4. set blocking mode
 *          : 5. bind to local address
 *          : 6. connect to remote hosts
 * INPUT    : szHostName    : host name
 *          : szServiceName : service name
 *          : nTimeOut      : time out 
 * OUTPUT   : NONE 
 * UPDATE   : NONE
 * RETURN   : -1    : connect fail
 *          : other : connected socket ID
 * AUTHOR	: ZZ-NODE/2000.12.21/songqufei
 * CALL     : gethostbyname()
 *          : getservbyname()
 *          : socket()
 *          : ioctl()
 *          : bind()
 *          : connect()
 *          : memset()
 ********************************************************************/
int TCP_EstablishConnection( char *szHostName, char *szServiceName, int nTimeOut )
{
    struct hostent * hp;
    struct servent * pstServEnt;
    struct sockaddr_in sin,sin1;
    int    sd;        /* socket descript */
    fd_set wr_set;
    struct timeval    tv;
    int    rc;
    
	sin1.sin_addr.s_addr = inet_addr(szHostName);
	if(sin1.sin_addr.s_addr == (u_int)-1){
		hp = gethostbyname(szHostName);
		if(!hp){
			DebugLog("未取得hostname");
			return -1;
		}
		if (hp->h_length > sizeof(sin1.sin_addr)) return -1;
		bcopy(hp->h_addr,(caddr_t)&sin1.sin_addr, hp->h_length);
	}

    /* -----<get service by name>----- */
	if((pstServEnt = getservbyport(htons(atoi(szServiceName)),"tcp" ))==NULL) {
		if((pstServEnt = getservbyname( szServiceName,"tcp" ))==NULL) {
			DebugLog("Unknown service name");
			return( -1 );
		}
    }

    /* -----<creat socket>----- */
    sd = socket(AF_INET, SOCK_STREAM, 0 );
    if(sd<0) {
        DebugLog("Socket failed");
        return ( -1 );
    }


    /* -----<bind to local address>----- */
    memset((char *)&sin,0,sizeof(struct sockaddr_in));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = 0;

    if(bind(sd, (char *)&sin, sizeof(struct sockaddr_in))<0) {
        DebugLog("Bind failed" );
        close( sd );
        return ( -1 );
    }

    /* -----<connect to remote host>----- */
    memset( &sin, 0, sizeof( struct sockaddr_in ) );
    sin.sin_family = AF_INET;
    sin.sin_port = pstServEnt -> s_port;
	sin.sin_addr.s_addr = sin1.sin_addr.s_addr;

    if(connect(sd, (char *)&sin, sizeof(struct sockaddr_in))<0) {
		close(sd);
		DebugLog("Connect failed" );
		return( -1 );
    }

    /* -----<we have connection>----- */
    return ( sd );
}


/********************************************************************
 * NAME     : Send_Ident
 * FUNCTION : 向指定端口传送本进程的身份信息
 * PROCESS  : 
 * INPUT    : sd : 端口ID
 * OUTPUT   : 
 * UPDATE   : 
 * RETURN   : IS_OK  : ok
 *			: IS_NG  : fail
 * AUTHOR	: ZZ-NODE/2000.12.21/songqufei
 * CALL     : 
 ********************************************************************/
int Send_Ident(int sd)
{
	char *pPacket;
	PacketHead *pPacketHead;
	ProcIdent  *pProcIdent;
	char	sHostName[64];
	
	pPacket = (char *)malloc(sizeof(PacketHead)+sizeof(ProcIdent));
	if(pPacket==NULL) {
		ErrorLog(ERROR_MEMORYALLOC,"SYSTEM","malloc error");
		return IS_NG;
	};
	
	memset(pPacket,0,sizeof(PacketHead)+sizeof(ProcIdent));

	pPacketHead = (PacketHead *)pPacket;
	pProcIdent  = (ProcIdent *)(pPacket+sizeof(PacketHead));
	
	pPacketHead->iPacketID = P_COM_SEND_IDENT;
	pPacketHead->lPacketSize = sizeof(PacketHead)+sizeof(ProcIdent);
	pPacketHead->iRecordNum  = 1;
	strcpy(pProcIdent->szType,szSubSystemID);
	sprintf(pProcIdent->szMachine,"%d",getpid());
	
	if(TCP_SendPacket(sd,pPacket)<0) {
		free(pPacket);
		ErrorLog(ERROR_SOCKET_WRITE,"SYSTEM","send packet error");
		return IS_NG;
	}

	free(pPacket);
	return IS_OK;
}

⌨️ 快捷键说明

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