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

📄 socketfunc.c

📁 一个C语言的聊天室源代码
💻 C
字号:
/*
	Version: 0.2.0(alpha)
	Author: Computer_xu
	Email: Computer_xu@sina.com
	HomePage: http://www.socketchat.com
	LastModify: 2001-05-22 (yyyy-mm-dd)
*/
#include "socketfunc.h"

/* #define DEBUGMODE */

pthread_mutex_t addsocket_mutex=PTHREAD_MUTEX_INITIALIZER;

/* 增加套接口的数量 */
/* 此函数只被AddSocket调用,而AddSocket在调用前已经对SOCKET队列加过锁了 */
void IncSocketBuf()
{
        SOCKET_INFO *p,*p1;
        int i;

        p=sysinfo.SOCKET_HEAD;
        while( p->next!=NULL ) p=p->next;
        for(i=0;i<sysinfo.SocketLeftWarning*2;i++)
        {
                p1=(SOCKET_INFO *)Malloc(sizeof(SOCKET_INFO));
                p1->status=0;
                p1->last=NULL;
                p1->next=NULL;

                p->next=p1;
                p=p->next;
        }
        sysinfo.SocketBufLen+=sysinfo.SocketLeftWarning;
}
/* 将某一用户添加到套接口列表中 */
int AddSocket(int socketfd, USERINFO *user)
{
        SOCKET_INFO *p,*p1;
	int rn;

        pthread_mutex_lock(&addsocket_mutex);
#ifdef DEBUGMODE
	printf("Enter AddSocket...\n");
#endif

	p=NULL;

	p1=sysinfo.SOCKET_HEAD;
	while(p1!=NULL)
	{
		if( p1->user==user && p1->status )
		{/* 用户可能使用<F5>进行了刷新,不是重复登陆,所以更新socket */
			close(p1->socketfd);
			break;
		}
		if( p1->status==0 )	p=p1;
		p1=p1->next;
	}
	if( p1==NULL )
	{
		sysinfo.onlineuser++;
		if( sysinfo.onlineuser > sysinfo.maxuser )
			sysinfo.maxuser=sysinfo.onlineuser;
		rn=1;
		if( p==NULL )
		{
			printf("Error In AddSocket\n");
			exit(1);
		}
		p1=p;
	}
	else	rn=0;
        p1->pid=getpid();
        p1->socketfd=socketfd;
        p1->status=1;
        time(&(p1->lasttime));
        p1->last=sysinfo.MSG_END;
        p1->user=user;

        if( sysinfo.onlineuser + sysinfo.SocketLeftWarning >= sysinfo.SocketBufLen ) IncSocketBuf();
	p1=sysinfo.SOCKET_HEAD;
        pthread_mutex_unlock(&addsocket_mutex);
#ifdef DEBUGMODE
	printf("Return From AddSocket\n");
#endif
	return(rn);
}
/* 将某一用户从套接口列表中删除 */
void DelSocket(USERINFO *user)
{
        SOCKET_INFO *p,*p1;
	ROOMINFO *rp;

        pthread_mutex_lock(&addsocket_mutex);

	p=sysinfo.SOCKET_HEAD;
	while(p!=NULL)
	{
                if( p->user==user && p->status )
		{
			p->status=0;
			close(p->socketfd);
		        sysinfo.onlineuser--;
			if(sysinfo.onlineuser<0)
			{
				printf("Error: OnlineUserNum < 0\n");
				sysinfo.onlineuser=0;
			}
		        rp=sysinfo.ROOM_HEAD;
		        while(rp!=NULL && rp->roomid!=user->roomid) rp=rp->next;
			if(rp!=NULL)
			{
				rp->usernum--;
				if(rp->usernum<0)
				{
					printf("Error: Room OnlineUserNum < 0\n");
					rp->usernum=0;
				}
			}
		}
		p=p->next;
        }
        if( sysinfo.onlineuser + sysinfo.SocketLeftWarning >= sysinfo.SocketBufLen ) IncSocketBuf();
        pthread_mutex_unlock(&addsocket_mutex);
}
/* 防止超时断线 */
void AntiTimeout()
{
        SOCKET_INFO *p1;
	int rn;
	char msg[1024];
	int flag=0;
	int AntiSec=30;

	pthread_detach(pthread_self());
	while(1)
	{
#ifdef DEBUGMODE
	        printf("Recycling in AntiTimeout...\n");
#endif
	        p1=sysinfo.SOCKET_HEAD;
        	while( p1!=NULL )
        	{
                	if( p1->status && (time(NULL) - p1->lasttime)>=AntiSec )
	                {
#ifdef DEBUGMODE
        	                printf("do anti-break\n");
#endif
                	        rn=write(p1->socketfd,"<!---->",strlen("<!---->"));
				if( rn==-1 && p1->status )
				{
					/* printf("Some one break line\n"); */
                	 		sprintf(msg,"<a href=\"\" OnClick=\"parent.SelectUser(\\\'%s\\\'); return false;\">%s</a> 掉线了!",p1->user->userid, p1->user->nickname);
				        AddWords(p1->user->roomid, "", "", 0, "", "", msg, 0);
					sprintf(msg,"<script>parent.RemoveUser('%s','%s','%s');</script>\n",p1->user->userid, p1->user->nickname, p1->user->sex);
					AddWords(p1->user->roomid, "", "", 0, "", "", msg, 2);
					LogOut(p1->user->nickname,p1->user->sid);
					flag=1;
				}
	                        p1->lasttime=time(NULL);
        	        }
                	p1=p1->next;
	        }
		if( flag )
		{
			ForceSend();
			flag=0;
		}
	        sleep(AntiSec);
	}
}
/* 获取socket连接的IP */
char * GetSocketIP(int connfd)
{
        struct sockaddr_in peeraddr;
        int addrlen;
        char *str;
	static char *error="0.0.0.0";

#ifdef DEBUGMODE
	printf("Enter GetSocketIP...\n");
#endif
	addrlen=sizeof(struct sockaddr_in);
        if( getpeername(connfd,(struct sockaddr *)&peeraddr,&addrlen)==0 )
		str=inet_ntoa(peeraddr.sin_addr);
	else	str=error;
#ifdef DEBUGMODE
	printf("Return From GetSocketIP.\n");
#endif
        return(str);
}
/* 获取socket连接的Port */
unsigned int GetSocketPort(int connfd)
{
        struct sockaddr_in peeraddr;
        int addrlen;

	addrlen=sizeof(struct sockaddr_in);
        getpeername(connfd,(struct sockaddr *)&peeraddr,&addrlen);
        return(ntohs(peeraddr.sin_port));
}

⌨️ 快捷键说明

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