Udp聊天室

服务器:

typedef struct msg
{
char type; //消息类型
char name[N];//客户名字
char text[N];//正文
}MSG;
typedef struct node
{
struct sockaddr_in adip;//存客户IP
struct node next;
}listnode;
listnode * linklist_t(void)
{
listnode
h =(listnode*)malloc(sizeof(listnode));
h->next = NULL;
return h;
}
void long_t(int sockfd,MSG msg,listnode h,struct sockaddr_in adip_t,socklen_t addrlen)
{
char l[N]={0};
sprintf (l,"%s long",msg.name);
strcpy(msg.text,l);
listnode
p =h->next;
while (p != NULL)
{
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr )&(p->adip),addrlen);
p= p->next;
}
p=(listnode
)malloc(sizeof(listnode));
p->adip = adip_t;
p->next=h->next;
h->next=p;

}

void chat_t(listnode h,MSG msg, struct sockaddr_in adip_t ,int sockfd,socklen_t addrlen)
{
char l[N]={0};
listnode
p =h->next;
sprintf (l,"%s txet: %s",msg.name,msg.text);
strcpy(msg.text,l);
while (p != NULL)
{
if(memcmp(&adip_t,&(p->adip),sizeof(adip_t)) != 0)
{
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&(p->adip),addrlen);
}
p= p->next;
}

}

void quit_t(int sockfd,listnode * h,MSG msg,struct sockaddr_in adip_t,socklen_t addrlen)
{
char l[N]={0};
sprintf (l,"%s quit",msg.name);
strcpy(msg.text,l);
listnode*p =h->next;
while (p != NULL)
{
if (memcmp(&adip_t,&(p->adip),sizeof(adip_t)) ==0 )
{
h->next = p->next;
free§;
}
if (h->next ==NULL)
{
memset(&msg,0,sizeof(msg));
break;
}
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&(p->adip),addrlen);
p= p->next;

}

}
int main(int argc, char argv[])
{
int sockfd,ret,pid;
struct sockaddr_in sockaddr, client;
MSG msg;
memset(&msg,0,sizeof(msg));
if (argc != 3)
{
printf (“请带参数”);
exit(-1);
}
socklen_t addrlen = sizeof(client);
sockfd = socket(AF_INET,SOCK_DGRAM,0);
memset(&sockaddr,0,sizeof(sockaddr));
sockaddr.sin_family=AF_INET;
sockaddr.sin_port = htons(atoi(argv[2]));
sockaddr.sin_addr.s_addr = inet_addr(argv[1]);
ret = bind (sockfd,(struct sockaddr
)&sockaddr,sizeof(sockaddr));
if (ret < 0)
{
perror(“bind”);
exit(-1);
}
pid = fork();
if (pid == 0)//写消息
{
strcpy(msg.name,“服务器”);
msg.type=‘B’;
while (1)
{
fgets(msg.text,N,stdin) ;
msg.text[strlen(msg.text)-1]=0;
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&sockaddr,addrlen);//向父进程发
}

}
else if (pid < 0 )
{
    perror("fork");
    exit(-1);
}
else //接消息
{
    listnode* H=linklist_t();//建链表
    while (1)
    {
       
        recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&client,&addrlen);
        printf ("%c\n%s %s\n   ",msg.type,msg.name,msg.text);
        switch (msg.type)
        {
        case 'L':
                  long_t(sockfd,msg,H,client,addrlen); //插链表      
            break; 
        case 'B':
                  chat_t(H,msg,client,sockfd,addrlen);//正文 
            break;
        case 'Q':
                  quit_t(sockfd,H,msg,client,addrlen);//删链表
            break;
        }

    }
}
return 0;

}

客户端 :

struct sockaddr_in {
__kernel_sa_family_t sin_family; /* Address family / 2字节
__be16 sin_port; /
Port number / 2字节
struct in_addr sin_addr; /
Internet address */ 4字节
char sin_zero[8]; // 8 bytes unused,作为填充
};
struct in_addr
{
in_addr_t s_addr; // u32 network address
};
#endif
typedef struct msg
{
char type; //消息类型
char name[N];//客户名字
char text[N];//正文
}MSG;
int main(int argc, char *argv[])
{
int sockfd,ret,pid;
struct sockaddr_in sockaddr, client;
MSG msg;
memset(&msg,0,sizeof(msg));
if (argc != 3)
{
printf (“请带参数”);
exit(-1);
}
socklen_t addrlen = sizeof(client);
sockfd = socket(AF_INET,SOCK_DGRAM,0);
memset(&sockaddr,0,sizeof(sockaddr));
sockaddr.sin_family=AF_INET;
sockaddr.sin_port = htons(atoi(argv[2]));
sockaddr.sin_addr.s_addr = inet_addr(argv[1]);

if (ret < 0)
{
    perror("bind");
    exit(-1);
}
printf ("name:");
fgets(msg.name,N,stdin);
msg.name[strlen(msg.name)-1]=0;
msg.type='L';
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&sockaddr,addrlen);
pid = fork();
if (pid == 0)//写消息
{
    while(1)
    {
        fgets(msg.text,N,stdin);
        msg.text[strlen(msg.text)-1]=0;
        if (strncmp(msg.text,"quit",4)==0)
        {
            msg.type='Q';
            sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&sockaddr,addrlen);
            memset(&msg,0,sizeof(msg));
            kill(getppid(),2);
            exit(0);
        }
        else 
        {
            msg.type = 'B';
            sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&sockaddr,addrlen);  
        }
    }
}
else if (pid < 0 )
{
    perror("fork");
    exit(-1);
}
else //接消息
{  
    while (1)
    {
        recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&client,&addrlen);
        printf ("%s\n",msg.text);
    } 
}
return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值