5.26作业

服务器端

#include <header.h>
#define SER_PORT 8888
#define SER_IP "192.168.125.101"
int sfd=-1;
typedef struct node
{
	char usrname[20];          //用户名
	struct sockaddr_in cin;    //客户端信息
	struct node *next;         //指针域
}node,*node_p;
struct buf
{
	char type;
	char usrname[20];
	char data[1024];
};

node_p create_link_list();   //创建链表头节点    
node_p create_node(char usrname[20],struct sockaddr_in cin);       //创建节点
int empty_link(node_p H);    //判空
int insert_head(node_p H,char usrname[20],struct sockaddr_in cin); //头插
void del_node(node_p H,char *usrname);                            //删除

int main(int argc, const char *argv[])
{
	//创建链表头节点
	node_p H=create_link_list();
	//创建服务器套接字
	sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd==-1)
	{
		perror("socket");
		return 1;
	}
	printf("socket success\n");
	
	//绑定服务器地址
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(SER_PORT);
	sin.sin_addr.s_addr=inet_addr(SER_IP);
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("bind");
		return 1;
	}
	struct sockaddr_in cin;
	socklen_t addrlen=sizeof(cin);
	char wbuf[1045];
	char xbuf[1045];
	char rbuf[1045];
	char type;
	char usrname[20];
	char data[1024];
	fd_set readfds,tempfds;
	FD_ZERO(&readfds);
	FD_SET(sfd,&readfds);
	FD_SET(0,&readfds);
	
	while(1)
	{
        //执行阻塞函数之前将文件描述符集合备份一份
        tempfds = readfds;

        //使用阻塞函数,检测文件描述符集合中是否有事件产生
        int res = select(sfd+1, &tempfds, NULL, NULL, NULL);
        if(res == -1)
		{
			perror("select error");
			return -1;
		}else if(res == 0)
		{
			printf("time out\n");
			return -1;
		}
		if(FD_ISSET(sfd,&tempfds))
		{
			char type='\0';
			memset(rbuf,0,sizeof(rbuf));
			memset(wbuf,0,sizeof(wbuf));
			memset(xbuf,0,sizeof(xbuf));
			memset(usrname,0,sizeof(usrname));
			memset(data,0,sizeof(data));
			recvfrom(sfd,rbuf,sizeof(rbuf),0,(struct sockaddr*)&cin,&addrlen);
			type=*rbuf;
			strncpy(usrname,rbuf+1,19);
			strcpy(data,rbuf+21);
			if(strcmp(data,"quit")==0)
			{
				del_node(H,usrname);
				printf("%s客户端已下线\n",usrname);
				char buf3[1045]="";
				memset(buf3,0,sizeof(buf3));
				strcat(buf3,usrname);
				strcat(buf3,":客户端已下线");
				node_p p=H->next;
				if(p==NULL)
				{
					printf("客户端已全部下线\n");

				}
				else
				{
					while(p!=NULL)
					{
						sendto(sfd,buf3,sizeof(buf3),0,(struct sockaddr*)&(p->cin),sizeof(p->cin));
						p=p->next;

					}
				} 
				continue;
			}
			if(type=='L')
			{
				if(empty_link(H))
				{
					insert_head(H,usrname,cin);
				}
				else 
				{

					int k=insert_head(H,usrname,cin);
					if(k==2)
					{
						memset(xbuf,0,sizeof(xbuf));
						strcpy(xbuf,"ipchongfu");
						sendto(sfd,xbuf,sizeof(xbuf),0,(struct sockaddr*)&cin,sizeof(cin));

					}
					else if(k==1)
					{
						memset(xbuf,0,sizeof(xbuf));
						strcpy(xbuf,"已有相同用户名登录");
						sendto(sfd,xbuf,sizeof(xbuf),0,(struct sockaddr*)&cin,sizeof(cin));
					}
					else if(k==0)
					{
						node_p p=H->next->next;
						do
						{
							memset(xbuf,0,sizeof(xbuf));
							strcpy(xbuf,usrname);
							int i=strlen(usrname);
							strcat(xbuf,":客户端已登录");
							sendto(sfd,xbuf,sizeof(xbuf),0,(struct sockaddr*)&(p->cin),sizeof(p->cin));
							p=p->next;
						}while(p!=NULL);
					}



				}

			}
			//聊天内容
			else if(type=='C')
			{
				memset(&wbuf,0,sizeof(wbuf));
				strcat(wbuf,usrname);
				strcat(wbuf,":");
				strcat(wbuf,data);
				node_p p=H->next;
				if(p->next==NULL)
				{
					;

				}
				else
				{
					while(p!=NULL)
					{
						if(strcmp(p->usrname,usrname)==0)
						{
							p=p->next;
							continue;
						}
						sendto(sfd,&wbuf,sizeof(wbuf),0,(struct sockaddr*)&(p->cin),sizeof(p->cin));
						p=p->next;

					}
				}
			}
		}
		if(FD_ISSET(0,&tempfds))
		{
			char buf2[1045]="";
			char buf1[1045];
			memset(buf2,0,sizeof(buf2));
			memset(buf2,0,sizeof(buf1));
			fgets(buf1,sizeof(buf1),stdin);
			buf1[strlen(buf1)-1]='\0';
			strcat(buf2,"服务器发来通知:");
			strcat(buf2,buf1);
			node_p p=H->next;
			if(p==NULL)
			{
				printf("无客户端,无需发送\n");

			}
			else
			{
				while(p!=NULL)
				{
					sendto(sfd,buf2,sizeof(buf2),0,(struct sockaddr*)&(p->cin),sizeof(p->cin));
					p=p->next;                                                                     

				}
			}
		}


	}


	return 0;
}
node_p create_link_list()
{
	node_p H=(node_p)malloc(sizeof(node));
	if(H==NULL)
	{
		printf("空间申请失败\n");
		return NULL;
	}
	H->next=NULL;
	return H;
}
node_p create_node(char usrname[20],struct sockaddr_in cin)
{
	node_p new=(node_p)malloc(sizeof(node));
	if(new == NULL)
	{
		printf("空间申请失败\n");
		return NULL;
	}
	strcpy(new->usrname,usrname);
	new->cin=cin;
	new->next=NULL;
	return new;
}
int insert_head(node_p H,char usrname[20],struct sockaddr_in cin)
{

	if(H==NULL)
	{
		printf("参数为空\n");
		return -1;
	}
	if(!empty_link(H))
	{
		node_p s=H->next;
		do
		{
			if(strcmp(usrname,s->usrname)==0)
			{
				return 1;
			}
			if(ntohs(cin.sin_port)==ntohs((s->cin).sin_port)&&inet_ntoa(cin.sin_addr)==inet_ntoa((s->cin).sin_addr))
			{
				return 2;
			}
			s=s->next;
		}while(s!=NULL);
	}
	node_p new=create_node(usrname,cin);
	new->next=H->next;
	H->next=new;
	char a='C';
	sendto(sfd,&a,sizeof(a),0,(struct sockaddr*)&cin,sizeof(cin));
	return 0;
}

int empty_link(node_p H)
{
	if(H==NULL)
	{
		printf("参数为空\n");
		return -1;
	}
	return H->next==NULL?1:0;
}
void del_node(node_p H,char *usrname)
{
	if(H==NULL)
	{
		printf("参数为空\n");
		return;
	}
	node_p p=H;
	while(p->next->next!=NULL)
	{
		node_p p1=p->next;
		if(strcmp(p1->usrname,usrname)==0)
		{
			p->next=p1->next;
			free(p1);
			p1=NULL;
			return;
		}
		p=p1;
	}
	node_p p1=p->next;
	p->next=NULL;
	free(p1);
	p1=NULL;
	return;
}

客户端

#include <header.h>
#define CLI_PORT 6666
#define CLI_IP "192.168.125.101"
#define SER_PORT 8888
#define SER_IP "192.168.125.101"
int main(int argc, const char *argv[])
{
	int cfd=socket(AF_INET,SOCK_DGRAM,0);
	if(cfd==-1)
	{
		perror("socket");
		return 1;
	}
	struct sockaddr_in cin;
	cin.sin_family=AF_INET;
	cin.sin_port=htons(CLI_PORT);
	cin.sin_addr.s_addr=inet_addr(CLI_IP);
	if(bind(cfd,(struct sockaddr*)&cin,sizeof(cin))==-1)
	{
		perror("bind");
		return 1;
	}
	//连接服务器
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(SER_PORT);
    sin.sin_addr.s_addr = inet_addr(SER_IP);
	char buf[1045]="L";
	char usrname[20];
	char Cbuf;
	while(1)
	{
		printf("请输入你的用户名:");
		fgets(usrname,sizeof(usrname),stdin);
		
		usrname[strlen(usrname)-1]='\0';
		strcat(buf,usrname);

		sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin));
		recvfrom(cfd,&Cbuf,sizeof(buf),0,NULL,NULL);
		if(Cbuf=='C')
		{
			break;
		}
	}
	printf("sadad\n");
	fflush(stdout);
	struct pollfd fdskl[2];
	fdskl[0].fd=0;
	fdskl[0].events=POLLIN;
	fdskl[1].fd=cfd;
	fdskl[1].events=POLLIN; 
	char wbuf[1045] = "";
    char rbuf[1045] = "";
    while(1)
    {
		memset(wbuf,0,sizeof(wbuf));
		memset(rbuf,0,sizeof(rbuf));
        int res = poll(fdskl, 2, -1);
        if(res == -1)
        {
            perror("poll error");
            return -1;
        }else if(res == 0){
         
            printf("time out\n");
            return -1;
        }
        if(fdskl[0].revents == POLLIN)
        {
			char sbuf[1045]="C";
			fgets(wbuf, sizeof(wbuf), stdin);
			wbuf[strlen(wbuf)-1] = '\0';
			if(strcmp(wbuf,"quit")==0)
			{
				close(cfd);
				return 1;
			}
			strcat(sbuf+1,usrname);
			strcat(sbuf+21,wbuf);

      
            sendto(cfd, sbuf, sizeof(sbuf), 0,(struct sockaddr*)&sin,sizeof(sin));
            printf("发送成功\n");
			memset(sbuf,0,sizeof(sbuf));
        }

        if(fdskl[1].revents == POLLIN)
        {
        
            bzero(rbuf, sizeof(rbuf));

            recvfrom(cfd, rbuf, sizeof(rbuf), 0,NULL,NULL);
            printf("%s\n", rbuf);
        }
    }
    close(cfd);return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值