#include "manage_chat.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <arpa/inet.h>
#include <stdlib.h>
//开启udp套结字
struct sockaddr_in * bind_server(int *sockfd,int i)
{
*sockfd = socket(AF_INET,SOCK_DGRAM,0);
int ret = *sockfd;
if(ret == -1){
perror("sockfd fail");
exit(EXIT_FAILURE);
}else{
printf("ret = %d\n",ret);
}
struct sockaddr_in *saddr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
memset(saddr,0,sizeof(*saddr));
saddr->sin_family = AF_INET;
saddr->sin_port = htons(8886 + i);
saddr->sin_addr.s_addr = htonl(INADDR_ANY);
//绑定套接字
ret = bind(*sockfd,(struct sockaddr *)saddr,sizeof(*saddr));
if(ret == -1){
perror("bind fail");
exit(EXIT_FAILURE);
}else{
printf("bind success!\n");
}
return saddr;
}
//建立初始化客户端
struct sockaddr_in * create_client_addr(int *len)
{
struct sockaddr_in *caddr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
memset(caddr,0,sizeof(*caddr));
*len = sizeof(*caddr);
return caddr;
}
int op_client(struct sockaddr_in * caddr,char op,manage* ma,int sockfd)
{
int ret = 0;
char msg_chat[1024] = {0};
memset(msg_chat,0,sizeof(msg_chat));
int caddr_len = sizeof(*caddr);
int msg_len = 0;
char server_msg[] = "请输入聊天信息\n";
switch(op){
case '0':
//登陆前先查找是否存在端口号,避免重复插入
if(!checkaddr(ma,caddr)){
register_client(ma,caddr);
}else{
printf("在线\n");
}
break;
case '1':
if(!checkaddr(ma,caddr)){
printf("请先登陆!\n");
break;
}
//chat,提醒用户发信息再收到信息
sendto(sockfd,server_msg,strlen(server_msg),0,(struct sockaddr *)caddr,caddr_len);
recvfrom(sockfd,msg_chat,sizeof(msg_chat),0,(struct sockaddr *)caddr,&caddr_len);//可得到客户端的ip和端口
msg_len = strlen(msg_chat);
chat(ma,sockfd,msg_chat,msg_len,caddr_len);//进行群发
break;
case '2':
//leave
leave(ma,caddr);
break;
case '3':
//群发
break;
default:
printf("操作失败\n");
break;
}
return 1;
}
//搭建udp服务器
int main(int argc,const char *argv[])
{
pid_t pid = fork();
if(pid < 0){
perror("pid fail");
exit(EXIT_FAILURE);
}else if(pid == 0){
//进行开启udp以及管理操作
manage client_manage;
init_manage(&client_manage);
//变量定义
int sockfd = 0;
int ret = 0;
struct sockaddr_in * saddr = bind_server(&sockfd,0);
struct sockaddr_in * caddr;
int caddr_len = 0;
char client_op[1024] = {0};//客户端的操作用一个字符即可
char op_cl[] = "请输入你要进行的操作\n";
//收到用户选择的操作方式,0为登陆,1为聊天,2为退出,而父进程为3,可以处理群聊
while(1){
//处理客户端过来的信息,创建客户端结构体
caddr = create_client_addr(&caddr_len);
char caddr_buf[64] = {0};
memset(caddr_buf,0,sizeof(caddr_buf));
memset(client_op,0,sizeof(client_op));
//准备收到客户端发来的命令
recvfrom(sockfd,client_op,sizeof(client_op),0,(struct sockaddr *)caddr,&caddr_len);//可得到客户端的ip和端口
// printf("客户端地址:%s :%d\n",inet_ntop(AF_INET,&caddr->sin_addr,caddr_buf,sizeof(caddr_buf)),ntohs(caddr->sin_port));
// printf("%s",client_op);
#if 1 //对客户端进行操作
op_client(caddr,client_op[0],&client_manage,sockfd);
//最后不用的时候free动态内存
#endif
}
}
//群发
// chat(ma,sockfd,msg_chat,msg_len,caddr_len);//进行群发
while(1);
return 0;
}