基于udp的聊天室

 服务器

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<unistd.h>
#define A 1		//登录
#define B 2		//聊天
#define C 3		//退出
#define M 1024

typedef struct{
    int type;
    char data[M];
    char name[20];
}MSG;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
typedef struct node{
    strcut sockaddr_in addr;
    struct node *next;
}linknode, *linklist;

void do_login(int sockfd,linklist H,struct sockaddr_in caddr, MSG* msg);
void do_chat(int sockfd,linklist H,struct sockaddr_in caddr, MSG *msg);
void do_quit(int sockfd, linklist H,struct sockaddr_in caddr, MSG *msg);

linklist create_linklist(){
    linklist H = (linklist)malloc(linknode);            //创建用户列表
    if(NULL == H){
    perror("malloc");
    return NULL;
    }
    H->next = NULL;
    return H;
}

int main()
{    
    MSG msg;
    linklist H;
    pid_t pid;
    
    int sockfd = socket(AF_INET, SOCK_DGRAM,0);
    if(sockfd < 0){
        perror("socket");
        exit(-1);
    }
    printf("socket is success,,\n") ;  
    
    struct sockfdaddr_in caddr,saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htos(7777);
    saddr.sin_addr.s.addr = inet_addr("127.0.0.1");

    int s_len = sizeof(saddr);
    int c_len = sizeof(caddr);

    int ret = bind(sockfd,(struct sockaddr *)&saddr,s_len);
    if(ret < 0){
        perror("bind");
        exit(-1);
      }
    printf("bind is success   \n");
    
    pid = fork();
    if(pid < 0)
    {
            perror("fork");
            exit(-1);
    }
    else if(pid == 0)
    {    
        bzero(&msg, sizeof(MSG));
        strcopy(msg.name,"sever");
        msg.type = B;
      while(1){
           fgets(msg.data,M, stdin);
            msg.data[strlen(msg.data)-1] = '\0';
            sendto(scokfd,&msg,sizeof(MSG),0,(struct sockaddr *)&caddr,c_len);            //服务器发消息,子进程发给父进程,再由父进程发给客户端
                
            }
    }
    else
    {
        H = create_linklist();
            while(1)
                {
                        recvfrom(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&caddr,&c_len);            //父进程接收客户端消息,在发给其他客户端
                        switch(msg.type)
                            {
                                case A:
                                    do_login(sockfd, H, caddr, &msg);
                                     break;
                                case B:
                                     do_chat(sockfd,H, caddr , &msg);
                                     break;
                                case C:
                                      do_quit(sockfd, H,caddr,&msg);
                                      break;                  
                                 default:
                                         puts("erro...");
                                         break;                     
                            }
                }
    }
    return 0;
}
void do_login(int sockfd, linklist H, struct sockaddr_in caddr, MSG*msg)
{
        linklist q;
        sprintf(msg->data,"%s login....",msg->name);
        int c_len = sizeof(caddr);
        q = (linklist)malloc(sizeof(linknode));
        if(NULL == q)
         {
            perror("malloc");
            exit(-1);
         } 
        q->addr = caddr;
        q->next = H->next;
        H->next = q;
        linklist p = H->next;
        while(p)
        {
            sendto(sockfd,msg,sizeof(MSG),0,(struct sockaddr *)&caddr,c_len);            
            p = p->next;
           }
    printf("%s  \n",msg->data);
}


void do_chat(int sockfd,,linklist H, struct sockaddr_in addr, MSG* msg )
{
     char buf[M] = {0};
      sprintf(buf,"%s  said : %s",msg->name,msg->data);
       strcpy(msg->data,buf);
        int c_len = sizeof(caddr); 
    linklist p = H->next;
    while(p)
    {
        if(memcmp(&caddr,&p->addr,c_len) != 0)        
            {
                sendto(sockfd,msg,sizeof(MSG),0,(struct sockaddr *)&caddr,c_len);
                
            }
            p = p->next;
    }  
    puts(msg->data);
}

void do_quit(int sockfd,,linklist H, struct sockaddr_in addr, MSG* msg )
{
    sprintf(msg->data,"%s  .quit...",msg->name);
    int c_len = sizeof(caddr);
    
    linklist p = H;
     linklist q;       
     while(p->next)
     {
        if(memsmp(&caddr,&p->next->addr,c_len) ==0)
        {
            q = p->next;
            p->next = q->next;
            free(q);
            q = NULL;   
         }
        else
            {
        sendto(sockfd,msg,sizeof(MSG),0,(struct sockadddr *)&caddr,c_len);
           p = p->next;
             }
    }
    puts(msg->data);   
}

客户端


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<signal.h>

#define A 1 //登录
#define B 2 //聊天
#define C 3 //退出

#define M 1024
typedef struct{
	int type;
	char data[M];
	char name[20];
}MSG;


int main()
{
	MSG msg;
	pid_t pid;
	int sockfd = socket(AF_INET,SOCK_DGRAM,0);
	if(sockfd <0)
	{
		perror("socket");
		exit(-1);
	}
	printf("socket %d is success...\n",sockfd);

	struct sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(9998);
	saddr.sin_addr.s_addr = inet_addr("192.168.91.131");

	int s_len = sizeof(saddr);
	//memset(&saddr,0,s_len);

	//登录
	puts("***************开始登录***********");
	msg.type = A;
	puts("输入的你的名字:");
	fgets(msg.name,20,stdin);
	msg.name[strlen(msg.name)-1] = '\0';
	int ret = sendto(sockfd, &msg,sizeof(MSG),0,(struct sockaddr *)&saddr,s_len);
	if(ret < 0)
	{
		perror("sendto");
		exit(-1);
	}
	pid = fork();
	if(pid<0)
	{
		perror("fork");
		exit(-1);
	}
	else if(pid == 0)  //子进程发送消息
	{
		printf("进入聊天室..\n");
		while(1)
		{	
			fgets(msg.data,M,stdin);
			msg.data[strlen(msg.data)-1] = '\0';
			if(strcmp(msg.data, "quit") == 0)//退出
			{
				msg.type = C;
				sendto(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&saddr,s_len);
				close(sockfd);
				kill(getppid(), SIGKILL);
				exit(0);
			}
			else	// 聊天
			{
				msg.type = B;
				sendto(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&saddr,s_len);
			}
		}
	}
	else				// 父进程接受消息
	{
		while(1)
		{
			recvfrom(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&saddr,&s_len);
			printf("%s\n",msg.data);
		}
	}

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值