8.11作业

 

 

服务器端:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
#include <pthread.h>

#define PORT 8888
#define IP "192.168.31.83"

struct sockaddr_in ser_addr,cli_addr;
typedef struct node
{
	struct sockaddr_in addr;
	struct node* next;
}list;

struct MSG
{
	char type;
	char name[10];
	char text[128];
}msg,msg_send;
//创建节点
list* list_create()
{
	list* l=(list*)malloc(sizeof(list));
	if(NULL == l)
	{
		printf("创建失败");
		return NULL;
	}
	l->next = NULL;
	return l;
}
int insert(list* l,struct sockaddr_in addr)
{
	if(NULL == l)
	{
		return -1;
	}
	list* pnew=(list*)malloc(sizeof(list));
	pnew->addr=addr;
	list*ptmp=l;
	while(ptmp->next!=NULL)
	{
		ptmp=ptmp->next;
	}
	ptmp->next=pnew;
	return 0;
}
//接收登录请求并发送
void do_login(int sfd,struct MSG msg,list* l,struct sockaddr_in cli_addr)
{
	printf("----%s上线----\n",msg.name);
	insert(l,cli_addr);
	list* p = l->next;
	
	while(p!= NULL)
	{
		msg.type='l';
		sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->addr,sizeof(p->addr));
		p=p->next;
	}
	return;
}
//聊天信息接收并发送
void do_chat(int sfd,struct MSG msg,list* t,struct sockaddr_in cli_addr)
{
	if(strcmp(msg.name,"管理员")!=0)
	{
		printf("[%s] : %s\n",msg.name,msg.text);
	}
	list* p=t->next;


	while(p!=NULL)
	{
		msg.type = 'c';
		if(sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->addr,sizeof(p->addr))<0)
		{
			perror("sendto");
		}
		p=p->next;
	}
	return;
}
//退出聊天
void do_quit(int sfd,struct MSG msg,list* l,struct sockaddr_in cli_addr)
{
	list* t = l;
	printf("----%s离线----\n",msg.name);
	list* pdel=NULL;
	while(t->next!=NULL)
	{
		msg.type='q';
		if(0==memcmp(&(t->next->addr),&cli_addr,sizeof(cli_addr)))
		{
			pdel=t->next;
			t->next=pdel->next;
			free(pdel);
			pdel=NULL;
		}else
		{
			t=t->next;
			if(sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&t->addr,sizeof(t->addr))<0)
			{
				perror("sendto");
			}
		}
	}
	return;
}
//系统发送消息
void* callback(void* arg)
{

	int sfd=*(int*)arg;
	while(1)
	{
		msg_send.type='c';
		strcpy(msg_send.name,"管理员");
		memset(msg_send.text,0,128);
		fgets(msg_send.text, 128, stdin);
		msg_send.text[strlen(msg_send.text)-1]=0;
		if(sendto(sfd, &msg_send, sizeof(msg_send), 0,(struct sockaddr*)&ser_addr, sizeof(ser_addr))< 0)
		{
			perror("sendto");
			return NULL;
		}
	}
}

int main(int argc, const char *argv[])
{
	//创建报式套接字
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd < 0)
	{
		perror("socket");
		
		return -1;
	}
	//填充网络信息结构体
	memset(&ser_addr,0,sizeof(ser_addr));
	ser_addr.sin_family      =AF_INET;
	ser_addr.sin_port        =htons(PORT);
	ser_addr.sin_addr.s_addr =inet_addr(IP);
	socklen_t addrlen = sizeof(ser_addr);
	socklen_t c_addrlen = sizeof(cli_addr);
	//绑定
	if(bind(sfd,(struct sockaddr*)&ser_addr,addrlen)<0)
	{
		perror("bind");
		return -1;
	}

	pthread_t tid;
	if(pthread_create(&tid,NULL,callback,(void*)&sfd)!=0)
	{
		perror("pthread_create");
		return -1;
	}
	list* l=list_create();
	while(1)
	{
		//接收客户端信息
		memset(&msg,0,sizeof(msg));
		if(recvfrom(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&cli_addr,&c_addrlen)<0)
		{
			perror("recvfrom");
			return -1;
		}
		switch(msg.type)
		{
		case 'l':
			do_login(sfd,msg,l,cli_addr);
			break;
		case 'c':
			do_chat(sfd,msg,l,cli_addr);
			break;
		case 'q':
			do_quit(sfd,msg,l,cli_addr);
			break;
		}
	}
	pthread_join(tid,NULL);
	return 0;
}

 客户端:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
#include <pthread.h>

#define PORT 8888
#define IP "192.168.31.83"

 struct MSG
{
	char type;
	char name[10];
	char text[128];
}msg,msg_send;
int sfd;
char buf[10]={0};
struct sockaddr_in ser_addr;
//接收服务器信息
void* callback(void* arg)
{
	socklen_t addrlen=*((socklen_t*)arg);
	while(1)
	{
		memset(&msg,0,sizeof(msg));
		if(recvfrom(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&ser_addr,&addrlen)<0)
		{
			perror("recvfrom");
			return NULL;
		}
		if(strcmp(buf,msg.name)==10)
		{
			//printf("%d",strcmp(buf,msg.name));

			continue;

		}else{
			switch(msg.type)
			{
			case 'l':
				printf("----%s上线----\n",msg.name);
				break;
			case 'c':
				printf("[%s] : %s\n",msg.name,msg.text);
				break;
			case 'q':
				printf("----%s下线-----\n",msg.name);
				break;
			}
		}
	}
}
int main(int argc, const char *argv[])
{
	sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd < 0)
	{
		perror("socket");
		return -1;
	}
	ser_addr.sin_family      =AF_INET;
	ser_addr.sin_port        =htons(PORT);
	ser_addr.sin_addr.s_addr =inet_addr(IP);
	socklen_t addrlen=sizeof(ser_addr);

	printf("请输入名字>>");
	msg_send.type='l';
	memset(msg_send.name,0,10);
	fgets(buf,10,stdin);
	strcpy(msg_send.name,buf);
	msg_send.name[strlen(msg_send.name)-1]=0;
	if(sendto(sfd,&msg_send,sizeof(msg_send),0,(struct sockaddr*)&ser_addr,sizeof(ser_addr))<0)
	{
		perror("sendto");
		return -1;
	}

	pthread_t tid;
	if(pthread_create(&tid,NULL,callback,(void*)&addrlen)!=0)
	{
		perror("pthread_create");
		return -1;
	
	}
	while(1)
	{ 
		memset(msg_send.text,0,128);
		fgets(msg_send.text,128,stdin);
		msg_send.text[strlen(msg_send.text)-1]=0;
		if(strcmp(msg_send.text,"quit")==0)
		{
			msg_send.type='q';
			sendto(sfd,&msg_send,sizeof(msg_send),0,(struct sockaddr*)&ser_addr,sizeof(ser_addr));
			exit(0);
		}else{
			msg_send.type='c';
		}
		if(sendto(sfd,&msg_send,sizeof(msg_send),0,(struct sockaddr*)&ser_addr,sizeof(ser_addr))<0)
		{
			perror("sendto");
			return -1;
		}
    }
	pthread_join(tid,NULL);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值