|
@@ -0,0 +1,1710 @@
|
|
|
|
|
+#include "include/tcp.h"
|
|
|
|
|
+#include "include/udp.h"
|
|
|
|
|
+#include "include/mychat.h"
|
|
|
|
|
+
|
|
|
|
|
+#if 1
|
|
|
|
|
+#define SELF_PORT_UDP 5002
|
|
|
|
|
+#define SELF_PORT_TCP 5003
|
|
|
|
|
+#define SELF_IP "192.168.188.136" //自己IP
|
|
|
|
|
+#define OTHER_PORT_UDP 5004
|
|
|
|
|
+#define OTHER_PORT_TCP 5005
|
|
|
|
|
+#define OTHER_IP "192.168.188.136" //他人IP
|
|
|
|
|
+#define BROADCAST_SEND_PORT_UDP 5200
|
|
|
|
|
+#define BROADCAST_RECV_PORT_UDP 5300
|
|
|
|
|
+#define BROADCAST_RECV_IP INADDR_ANY //广播IP
|
|
|
|
|
+#define BROADCAST_SEND_IP INADDR_BROADCAST //广播IP
|
|
|
|
|
+
|
|
|
|
|
+#else
|
|
|
|
|
+#define OTHER_PORT_UDP 5002
|
|
|
|
|
+#define OTHER_PORT_TCP 5003
|
|
|
|
|
+#define OTHER_IP "192.168.188.136" //自己IP
|
|
|
|
|
+#define SELF_PORT_UDP 5004
|
|
|
|
|
+#define SELF_PORT_TCP 5005
|
|
|
|
|
+#define SELF_IP "192.168.188.136" //他人IP
|
|
|
|
|
+#define BROADCAST_RECV_PORT_UDP 5200
|
|
|
|
|
+#define BROADCAST_SEND_PORT_UDP 5300
|
|
|
|
|
+#define BROADCAST_RECV_IP INADDR_ANY //广播IP
|
|
|
|
|
+#define BROADCAST_SEND_IP INADDR_BROADCAST //广播IP
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#define NO_FIND 0
|
|
|
|
|
+#define HAVE_FIND 1
|
|
|
|
|
+
|
|
|
|
|
+LIST_HEAD(udp_data_head); //聊天数据
|
|
|
|
|
+struct list_head *p1 = NULL;
|
|
|
|
|
+struct servmsg_udp *pos1 = NULL;
|
|
|
|
|
+
|
|
|
|
|
+LIST_HEAD(udp_online_head); //用户列表
|
|
|
|
|
+struct list_head *p2 = NULL;
|
|
|
|
|
+struct user_info *pos2 = NULL;
|
|
|
|
|
+
|
|
|
|
|
+LIST_HEAD(tcp_data_head); //下载数据
|
|
|
|
|
+struct list_head *p3 = NULL;
|
|
|
|
|
+struct servmsg_tcp *pos3 = NULL;
|
|
|
|
|
+
|
|
|
|
|
+LIST_HEAD(tcp_accept_head); //下载允许用户
|
|
|
|
|
+struct list_head *p4 = NULL;
|
|
|
|
|
+struct down_info *pos4 = NULL;
|
|
|
|
|
+
|
|
|
|
|
+int I_UDP=0; //聊天数
|
|
|
|
|
+int J_UDP=0; //上线数
|
|
|
|
|
+int I_TCP=0; //文件数
|
|
|
|
|
+int J_TCP=0; //下载数
|
|
|
|
|
+
|
|
|
|
|
+pthread_mutex_t lock1;
|
|
|
|
|
+char DATAIN[UDP_MAXSIZE+1]; //输入的内容
|
|
|
|
|
+int DOWN_IF_IN = 0; //下载确认输入
|
|
|
|
|
+int CHANGE_AIM_IF_IN =0; //改变对象选择输入
|
|
|
|
|
+int IF_CHAT_IN = 1; //等待聊天输入完成
|
|
|
|
|
+int IF_ORD_IN = 1; //等待命令输入完成
|
|
|
|
|
+
|
|
|
|
|
+int DOWN_READY_IF = 0; //下载准备
|
|
|
|
|
+int IF_DOWN = 0; //0已经下线,1已经上线
|
|
|
|
|
+
|
|
|
|
|
+char UP_WAY[50]; //上传路径
|
|
|
|
|
+char DOWN_WAY[50]; //下载路径
|
|
|
|
|
+char DOWN_NAME[20]; //下载文件名
|
|
|
|
|
+
|
|
|
|
|
+char MY_NAME[20]; //自己的名字
|
|
|
|
|
+struct sockaddr_in SELF_UDP_ADDR; //自己UDP信息,上线信息
|
|
|
|
|
+struct sockaddr_in SELF_TCP_ADDR; //自己TCP信息,上线信息
|
|
|
|
|
+
|
|
|
|
|
+//char AIM_NAME[20]; //目标的名字
|
|
|
|
|
+struct sockaddr_in OTHER_UDP_ADDR;//他人UDP信息,临时通讯地址
|
|
|
|
|
+struct sockaddr_in OTHER_TCP_ADDR;//他人TCP信息,临时通讯地址
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/**************************************以下UDP部分*******************************************/
|
|
|
|
|
+/*UDP发送数据*/
|
|
|
|
|
+void play(void);
|
|
|
|
|
+void up_ord(void);
|
|
|
|
|
+void order_or_chat(char *ord);
|
|
|
|
|
+char read_file(struct sockaddr_in *cin, char *way);
|
|
|
|
|
+char *addr_return_name(struct sockaddr_in *addr);
|
|
|
|
|
+struct sockaddr_in *name_reurn_addr(int type, char *aim_name);
|
|
|
|
|
+int send_online_info(void)
|
|
|
|
|
+{
|
|
|
|
|
+ /*上线信息*/
|
|
|
|
|
+ struct msg_udp usron;
|
|
|
|
|
+ //填写数据包信息
|
|
|
|
|
+ usron.type_udp = LOG_IN; //聊天类型
|
|
|
|
|
+ strcpy(usron.self_name, MY_NAME); //自己名字
|
|
|
|
|
+ strcpy(usron.aim_name, "*no*"); //目标名字
|
|
|
|
|
+ usron.data_size = strlen("*no*"); //消息大小
|
|
|
|
|
+ strcpy(usron.data, "*no*"); //数据
|
|
|
|
|
+ memcpy(&usron.self_addr_udp, &SELF_UDP_ADDR, sizeof(SELF_UDP_ADDR)); //自己UDP地址
|
|
|
|
|
+ memcpy(&usron.self_addr_tcp, &SELF_TCP_ADDR, sizeof(SELF_TCP_ADDR)); //自己TCP地址
|
|
|
|
|
+ strcpy((char *)&usron.aim_addr_udp, "*no*"); //目标地址
|
|
|
|
|
+
|
|
|
|
|
+ int ret = -1;
|
|
|
|
|
+ ret = udp_broad_send_to(BROADCAST_SEND_IP, BROADCAST_SEND_PORT_UDP, &usron, sizeof(usron)); //广播IP 255
|
|
|
|
|
+ if(ret == -1)
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("广播失败!\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*UDP登入*/
|
|
|
|
|
+void loading_udp(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret = -1;
|
|
|
|
|
+ if (IF_DOWN == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ do
|
|
|
|
|
+ {
|
|
|
|
|
+ ret = send_online_info();
|
|
|
|
|
+ pr_debug("正在登入中...\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ while (ret != 0);
|
|
|
|
|
+ IF_DOWN = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int udp_linked_list_add(struct msg_udp *msg)
|
|
|
|
|
+{
|
|
|
|
|
+ switch (msg->type_udp)
|
|
|
|
|
+ {
|
|
|
|
|
+ case LOG_IN: //登入
|
|
|
|
|
+ {
|
|
|
|
|
+ char *name_p = msg->self_name;
|
|
|
|
|
+ if(!(name_p && name_p > 0 && strlen(name_p) < 20 && strncmp(name_p, MY_NAME, strlen(MY_NAME)) != 0))
|
|
|
|
|
+ break;
|
|
|
|
|
+ int finded_name = NO_FIND;
|
|
|
|
|
+ struct list_head *n2 = NULL;
|
|
|
|
|
+ list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
|
|
|
|
|
+ {
|
|
|
|
|
+ pos2 = list_entry(p2, struct user_info, user_info_list);
|
|
|
|
|
+ if (strncmp(msg->self_name, pos2->user_name, strlen(pos2->user_name)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ finded_name = HAVE_FIND;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (finded_name != HAVE_FIND) //没有找到此用户,则加入
|
|
|
|
|
+ {
|
|
|
|
|
+ struct user_info *newmsg;
|
|
|
|
|
+ newmsg = (struct user_info *)malloc(sizeof(struct user_info));
|
|
|
|
|
+
|
|
|
|
|
+ //1.填写IP与端口
|
|
|
|
|
+ memcpy(&(newmsg->user_name), msg->self_name, sizeof(msg->self_name)); //客户名
|
|
|
|
|
+ (newmsg->id)++; //id
|
|
|
|
|
+ memcpy(&(newmsg->cli_addr_udp), &msg->self_addr_udp, sizeof(msg->self_addr_udp)); //UDP IP地址与端口号
|
|
|
|
|
+ memcpy(&(newmsg->cli_addr_tcp), &msg->self_addr_tcp, sizeof(msg->self_addr_tcp)); //TCP IP地址与端口号
|
|
|
|
|
+
|
|
|
|
|
+ //2.加入链表
|
|
|
|
|
+ list_add_tail(&newmsg->user_info_list, &udp_online_head);
|
|
|
|
|
+ J_UDP++;
|
|
|
|
|
+
|
|
|
|
|
+ //3.显示客户登入信息
|
|
|
|
|
+ printf("[%s]上线了!\n", msg->self_name);
|
|
|
|
|
+
|
|
|
|
|
+ char addr[16];
|
|
|
|
|
+ u_short port1,port2;
|
|
|
|
|
+ inet_ntop(AF_INET, (void *)&(newmsg->cli_addr_udp.sin_addr.s_addr), addr, sizeof(addr));
|
|
|
|
|
+ port1 = ntohs(newmsg->cli_addr_udp.sin_port);
|
|
|
|
|
+ port2 = ntohs(newmsg->cli_addr_tcp.sin_port);
|
|
|
|
|
+ printf("客户上线信息:%s:UDP[%d] TCP[%d]\n", addr, port1, port2);
|
|
|
|
|
+
|
|
|
|
|
+ finded_name = NO_FIND;
|
|
|
|
|
+
|
|
|
|
|
+ //4.重新广播
|
|
|
|
|
+ int ret = -1;
|
|
|
|
|
+ ret = send_online_info(); // 自己“已上线”信息
|
|
|
|
|
+ do{
|
|
|
|
|
+ sleep(3);
|
|
|
|
|
+ ret = send_online_info(); // 自己“已上线”信息
|
|
|
|
|
+ }while (ret == -1);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case OFFLINE: //下线
|
|
|
|
|
+ {
|
|
|
|
|
+ struct list_head *n2 = NULL;
|
|
|
|
|
+ list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
|
|
|
|
|
+ {
|
|
|
|
|
+ pos2 = list_entry(p2, struct user_info, user_info_list);
|
|
|
|
|
+ if (strncmp(msg->self_name, pos2->user_name, strlen(pos2->user_name)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("[%s]下线!\n", pos2->user_name);
|
|
|
|
|
+
|
|
|
|
|
+ J_UDP--;
|
|
|
|
|
+ list_del(&pos2->user_info_list); //删除用户
|
|
|
|
|
+ free(pos2);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case CHAT_ONE: //私聊
|
|
|
|
|
+ {
|
|
|
|
|
+ struct servmsg_udp *newmsg;
|
|
|
|
|
+ newmsg = (struct servmsg_udp *)malloc(sizeof(struct servmsg_udp));
|
|
|
|
|
+
|
|
|
|
|
+ if(strncmp(msg->aim_name, MY_NAME, strlen(MY_NAME)) == 0) //接受的数据包,如果是发给自己的,就加入链表;否则丢弃
|
|
|
|
|
+ {
|
|
|
|
|
+ //1.添加尾部
|
|
|
|
|
+ memcpy(&(newmsg->recvmsg), msg, sizeof(struct msg_udp)); //数据
|
|
|
|
|
+
|
|
|
|
|
+ //2.加入链表
|
|
|
|
|
+ list_add_tail(&newmsg->servmsg_udp_list, &udp_data_head);
|
|
|
|
|
+ I_UDP++;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //修改聊天对象
|
|
|
|
|
+ char *aim_name, *aim_name_of_other;
|
|
|
|
|
+ struct sockaddr_in *addr_udp_find;
|
|
|
|
|
+ aim_name = addr_return_name(&msg->self_addr_udp);
|
|
|
|
|
+ aim_name_of_other = addr_return_name(&OTHER_UDP_ADDR);
|
|
|
|
|
+ addr_udp_find = name_reurn_addr(1, aim_name);
|
|
|
|
|
+
|
|
|
|
|
+// pr_debug("上个对话:%s, 将要对话:%s\n",aim_name,aim_name_of_other);
|
|
|
|
|
+ if(aim_name == NULL || addr_udp_find == NULL)
|
|
|
|
|
+ ;
|
|
|
|
|
+ else if (aim_name_of_other == NULL)
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("修改对象为:%s\n->",aim_name);
|
|
|
|
|
+ udp_info_check(addr_udp_find);
|
|
|
|
|
+ bzero(&OTHER_UDP_ADDR, sizeof(struct sockaddr_in));
|
|
|
|
|
+ memcpy(&OTHER_UDP_ADDR, addr_udp_find, sizeof(struct sockaddr_in));
|
|
|
|
|
+ aim_name = addr_return_name(&OTHER_UDP_ADDR);
|
|
|
|
|
+ pr_debug("现在对象为:%s\n",aim_name);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if(strncmp(aim_name, aim_name_of_other, strlen(aim_name_of_other)) != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ char reply;
|
|
|
|
|
+
|
|
|
|
|
+ printf("是否改变聊天对象为:[%s]? ++y/++n", aim_name);
|
|
|
|
|
+
|
|
|
|
|
+ while(CHANGE_AIM_IF_IN != 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("等待输入...\n");
|
|
|
|
|
+ sleep(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ reply = DATAIN[0];
|
|
|
|
|
+ CHANGE_AIM_IF_IN = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if(reply == 'y')
|
|
|
|
|
+ {
|
|
|
|
|
+ bzero(&OTHER_UDP_ADDR, sizeof(struct sockaddr_in));
|
|
|
|
|
+ memcpy(&OTHER_UDP_ADDR, addr_udp_find, sizeof(struct sockaddr_in));
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (reply == 'n')
|
|
|
|
|
+ {
|
|
|
|
|
+ ;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case CHAT_ALL: //群发
|
|
|
|
|
+ {
|
|
|
|
|
+ struct servmsg_udp *newmsg;
|
|
|
|
|
+ newmsg = (struct servmsg_udp *)malloc(sizeof(struct servmsg_udp));
|
|
|
|
|
+
|
|
|
|
|
+ //1.添加尾部
|
|
|
|
|
+ memcpy(&(newmsg->recvmsg), msg, sizeof(struct msg_udp)); //数据
|
|
|
|
|
+
|
|
|
|
|
+ //2.加入链表
|
|
|
|
|
+ list_add_tail(&newmsg->servmsg_udp_list, &udp_data_head);
|
|
|
|
|
+ I_UDP++;
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case REFRESH: //列表 登入类型中 已加入
|
|
|
|
|
+ {
|
|
|
|
|
+/*
|
|
|
|
|
+ pr_debug("[%s]请求列表!\n", msg->self_name);
|
|
|
|
|
+
|
|
|
|
|
+ struct servmsg_udp *newmsg;
|
|
|
|
|
+ newmsg = (struct servmsg_udp *)malloc(sizeof(struct servmsg_udp));
|
|
|
|
|
+ //1.添加尾部
|
|
|
|
|
+ memcpy(&(newmsg->recvmsg), &msg, sizeof(msg)); //数据
|
|
|
|
|
+
|
|
|
|
|
+ //2.修改类型,通过私聊发送
|
|
|
|
|
+ newmsg->recvmsg.type_udp = CHAT_ONE;
|
|
|
|
|
+
|
|
|
|
|
+ //3.添加内容data
|
|
|
|
|
+ strcpy(newmsg->recvmsg.data, "用户列表:");
|
|
|
|
|
+ struct list_head *n2 = NULL;
|
|
|
|
|
+ list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
|
|
|
|
|
+ {
|
|
|
|
|
+ pos2 = list_entry(p2, struct user_info, user_info_list);
|
|
|
|
|
+ sprintf(newmsg->recvmsg.data, "[%s] [%s]", newmsg->recvmsg.data, pos2->user_name);
|
|
|
|
|
+ }
|
|
|
|
|
+ sprintf(newmsg->recvmsg.data, "%s%c", newmsg->recvmsg.data, '\n');
|
|
|
|
|
+ pr_debug("用户列表:%s\n", newmsg->recvmsg.data);
|
|
|
|
|
+ //4.加入链表
|
|
|
|
|
+ list_add_tail(&newmsg->list, &udp_data_head);
|
|
|
|
|
+ I_UDP++;
|
|
|
|
|
+*/
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case UPLOAD: //上传
|
|
|
|
|
+ {
|
|
|
|
|
+ struct servmsg_udp *newmsg;
|
|
|
|
|
+ newmsg = (struct servmsg_udp *)malloc(sizeof(struct servmsg_udp));
|
|
|
|
|
+ /*1.填写IP与端口*/
|
|
|
|
|
+ memcpy(&(newmsg->recvmsg.self_name), msg->self_name, sizeof(msg->self_name)); //客户名
|
|
|
|
|
+ memcpy(&(newmsg->recvmsg.aim_addr_udp), &msg->aim_addr_udp, sizeof(msg->aim_addr_udp)); //IP地址与端口号
|
|
|
|
|
+
|
|
|
|
|
+ /*3.填写数据*/
|
|
|
|
|
+ char *cut_p;
|
|
|
|
|
+ cut_p = strtok(msg->data, "_");
|
|
|
|
|
+ cut_p = strtok(NULL, "_");
|
|
|
|
|
+ sprintf(newmsg->recvmsg.data, "%s:%s\n", msg->self_name, cut_p);
|
|
|
|
|
+ newmsg->recvmsg.data[UDP_MAXSIZE] = 0;
|
|
|
|
|
+ newmsg->recvmsg.data_size = strlen(newmsg->recvmsg.data);
|
|
|
|
|
+ pr_debug("UDP接收加入链表【%s】\n", cut_p);
|
|
|
|
|
+ /*3.填加到链表*/
|
|
|
|
|
+ list_add_tail(&newmsg->servmsg_udp_list, &udp_data_head);
|
|
|
|
|
+ I_UDP++;
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case DOWNLOAD: //下载
|
|
|
|
|
+ {
|
|
|
|
|
+ // 待续
|
|
|
|
|
+ /*1.下载列表*/
|
|
|
|
|
+ if (strncmp(msg->data, "list", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ //查找list
|
|
|
|
|
+ struct list_head *n1 = NULL;
|
|
|
|
|
+ list_for_each_safe(p1, n1, &udp_data_head) //安全遍历聊天
|
|
|
|
|
+ {
|
|
|
|
|
+ pos1 = list_entry(p1, struct servmsg_udp, servmsg_udp_list);
|
|
|
|
|
+ if (pos1->recvmsg.type_udp == UPLOAD)
|
|
|
|
|
+ {
|
|
|
|
|
+ udp_send_to(inet_ntoa(msg->aim_addr_udp.sin_addr),msg->aim_addr_udp.sin_port, \
|
|
|
|
|
+ &pos1->recvmsg, sizeof(pos1->recvmsg));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ char read_file(struct sockaddr_in *cin, char *way);
|
|
|
|
|
+ /*2.遍历查找UPLOAD,修改接受者(不用删除下载链表)*/
|
|
|
|
|
+ if (strncmp(msg->data, "start", 5) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ char *cut_p;
|
|
|
|
|
+ struct sockaddr_in aim_tcp_addr;//他人信息
|
|
|
|
|
+ cut_p = strtok(msg->data, ":");
|
|
|
|
|
+ cut_p = strtok(NULL, ":");
|
|
|
|
|
+ /********************根据UDP修改客户地址********************/
|
|
|
|
|
+ aim_tcp_addr.sin_family = AF_INET;
|
|
|
|
|
+ aim_tcp_addr.sin_port = msg->aim_addr_udp.sin_port;
|
|
|
|
|
+ aim_tcp_addr.sin_addr.s_addr = msg->aim_addr_udp.sin_addr.s_addr;
|
|
|
|
|
+ bzero(aim_tcp_addr.sin_zero, 8);
|
|
|
|
|
+ /***********************************************************/
|
|
|
|
|
+ if (access(cut_p, F_OK) != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ read_file(&aim_tcp_addr, cut_p);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ printf("文件不存在!\n");
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ default:
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void *udp_linked_list_manage(void *arg)
|
|
|
|
|
+{
|
|
|
|
|
+ sleep(2);
|
|
|
|
|
+ pr_debug("UDP链表管理\n");
|
|
|
|
|
+ static int num_i=0, num_j=0;
|
|
|
|
|
+ while (1)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (num_j != J_UDP)
|
|
|
|
|
+ pr_debug("** 上线:%d **\n", J_UDP);
|
|
|
|
|
+ /********************************************************************
|
|
|
|
|
+ if (num_i != I_UDP || num_j != J_UDP)
|
|
|
|
|
+ pr_debug("** 聊天:%d,上线:%d **\n", I_UDP, J_UDP);
|
|
|
|
|
+ *********************************************************************/
|
|
|
|
|
+ num_i = I_UDP;
|
|
|
|
|
+ num_j = J_UDP;
|
|
|
|
|
+
|
|
|
|
|
+ //1.通过对小结构体的遍历,来获得大结构体的数据
|
|
|
|
|
+ struct list_head *n1 = NULL;
|
|
|
|
|
+ list_for_each_safe(p1, n1, &udp_data_head) //安全遍历聊天
|
|
|
|
|
+ {
|
|
|
|
|
+ pos1 = list_entry(p1, struct servmsg_udp, servmsg_udp_list);
|
|
|
|
|
+ //2.根据类型,处理数据
|
|
|
|
|
+ // printf("类型:%d,data=%s\n", pos1->recvmsg.type_udp, pos1->recvmsg.data);
|
|
|
|
|
+ switch (pos1->recvmsg.type_udp)
|
|
|
|
|
+ {
|
|
|
|
|
+ case LOG_IN: //登入
|
|
|
|
|
+ {
|
|
|
|
|
+ //登入信息不需要处理,直接用--list命令可查看的登入者信息
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case OFFLINE: //下线
|
|
|
|
|
+ {
|
|
|
|
|
+ //有用户下线,则直接删除登入者的链表信息
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case REFRESH: //列表
|
|
|
|
|
+ {
|
|
|
|
|
+ //在接收线程,修改类型,通过私聊发送出
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case UPLOAD: //上传
|
|
|
|
|
+ {
|
|
|
|
|
+ //在接收线程处理了
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case DOWNLOAD: //下载
|
|
|
|
|
+ {
|
|
|
|
|
+ //在接收线程处理了
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case CHAT_ONE: //私聊
|
|
|
|
|
+ {
|
|
|
|
|
+ /*提取聊天包,打印*/
|
|
|
|
|
+ if(strncmp(pos1->recvmsg.aim_name, MY_NAME, strlen(MY_NAME)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ char addr[16];
|
|
|
|
|
+ u_short port;
|
|
|
|
|
+ inet_ntop(AF_INET, (void *)&(pos1->recvmsg.self_addr_udp.sin_addr.s_addr), addr, sizeof(addr));
|
|
|
|
|
+ port = ntohs(pos1->recvmsg.self_addr_udp.sin_port);
|
|
|
|
|
+
|
|
|
|
|
+ pr_debug("发送者:%s,接收者:%s\n", pos1->recvmsg.self_name, pos1->recvmsg.aim_name);
|
|
|
|
|
+ pr_debug("发送客户地址:%s:%d\n", addr, port);
|
|
|
|
|
+ pr_debug("内容[%d字节]:%s \n", pos1->recvmsg.data_size, pos1->recvmsg.data);
|
|
|
|
|
+
|
|
|
|
|
+ if (strncmp(pos1->recvmsg.data, "quit", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("[%s]结束与[%s]的聊天!\n", pos1->recvmsg.self_name, pos1->recvmsg.aim_name);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ I_UDP--;
|
|
|
|
|
+ list_del(&pos1->servmsg_udp_list); //处理完后删除聊天
|
|
|
|
|
+ free(pos1);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case CHAT_ALL: //群聊
|
|
|
|
|
+ {
|
|
|
|
|
+ /*提取聊天包,发送给目标*/
|
|
|
|
|
+ struct list_head *n2 = NULL;
|
|
|
|
|
+ list_for_each_safe(p2, n2, &udp_online_head) //重新遍历上线
|
|
|
|
|
+ {
|
|
|
|
|
+ pos2 = list_entry(p2, struct user_info, user_info_list);
|
|
|
|
|
+ if (strncmp(pos1->recvmsg.aim_name, pos2->user_name, strlen(pos2->user_name)) == 0)
|
|
|
|
|
+ {//在用户列表中,找到了
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ pr_debug("发送者:%s,接收者:%s\n", pos1->recvmsg.self_name, pos1->recvmsg.aim_name);
|
|
|
|
|
+
|
|
|
|
|
+ char addr[16];
|
|
|
|
|
+ u_short port;
|
|
|
|
|
+ inet_ntop(AF_INET, (void *)&(pos2->cli_addr_udp.sin_addr.s_addr), addr, sizeof(addr));
|
|
|
|
|
+ port = ntohs(pos2->cli_addr_udp.sin_port);
|
|
|
|
|
+ pr_debug("发送客户地址:%s:%d\n", addr, port);
|
|
|
|
|
+
|
|
|
|
|
+ /*截取聊天信息*/
|
|
|
|
|
+ pos1->recvmsg.data[UDP_MAXSIZE] = 0;
|
|
|
|
|
+ printf("内容[%d字节]:%s \n", pos1->recvmsg.data_size, pos1->recvmsg.data);
|
|
|
|
|
+
|
|
|
|
|
+ if (strncmp(pos1->recvmsg.data, "quit", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("[%s]结束群聊!\n", pos1->recvmsg.self_name);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ port = ntohs(pos2->cli_addr_udp.sin_port);
|
|
|
|
|
+ udp_send_to(inet_ntoa(pos2->cli_addr_udp.sin_addr),port, \
|
|
|
|
|
+ &pos1->recvmsg, sizeof(pos1->recvmsg));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ I_UDP--;
|
|
|
|
|
+ list_del(&pos1->servmsg_udp_list); //处理完后删除聊天
|
|
|
|
|
+ free(pos1);
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ default:
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*UDP接收数据*/
|
|
|
|
|
+
|
|
|
|
|
+void *recv_udp(void *arg)
|
|
|
|
|
+{
|
|
|
|
|
+ sleep(1);
|
|
|
|
|
+ pr_debug("UDP接收数据\n");
|
|
|
|
|
+
|
|
|
|
|
+ struct sockaddr_in cin; //发送者信息
|
|
|
|
|
+ char ret;
|
|
|
|
|
+
|
|
|
|
|
+ /*3.接收数据包*/
|
|
|
|
|
+ struct msg_udp msg; //收到他人发来的包
|
|
|
|
|
+ while (1)
|
|
|
|
|
+ {
|
|
|
|
|
+ ret = udp_recv_from(SELF_IP, SELF_PORT_UDP, &cin, &msg);
|
|
|
|
|
+ if (ret < 0) //真正出错了
|
|
|
|
|
+ {
|
|
|
|
|
+ perror("recvfrom");
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ //加入链表
|
|
|
|
|
+ udp_linked_list_add(&msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*UDP广播接收数据*/
|
|
|
|
|
+void *recv_broad_udp(void *arg)
|
|
|
|
|
+{
|
|
|
|
|
+ sleep(1);
|
|
|
|
|
+ pr_debug("UDP广播接收数据\n");
|
|
|
|
|
+
|
|
|
|
|
+ struct sockaddr_in cin; //发送者信息
|
|
|
|
|
+ char ret;
|
|
|
|
|
+
|
|
|
|
|
+ /*3.接收数据包*/
|
|
|
|
|
+ struct msg_udp msg; //收到他人发来的包
|
|
|
|
|
+ while (1)
|
|
|
|
|
+ {
|
|
|
|
|
+ ret = udp_broad_recv_from(BROADCAST_RECV_IP, BROADCAST_RECV_PORT_UDP, &cin, &msg);
|
|
|
|
|
+ if (ret < 0) //真正出错了
|
|
|
|
|
+ {
|
|
|
|
|
+ perror("recvfrom");
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ //加入链表
|
|
|
|
|
+ pr_debug("UDP广播接收数据类型:%d\n", msg.type_udp);
|
|
|
|
|
+ udp_linked_list_add(&msg);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+/******************************************以上UDP部分******************************************************/
|
|
|
|
|
+
|
|
|
|
|
+/******************************************各功能模块*******************************************************/
|
|
|
|
|
+
|
|
|
|
|
+/*私聊*/
|
|
|
|
|
+void talk(char *name, char *str)
|
|
|
|
|
+{
|
|
|
|
|
+ if(!name && !str)
|
|
|
|
|
+ pr_debug("私聊\n");
|
|
|
|
|
+
|
|
|
|
|
+ int ret;
|
|
|
|
|
+ static char aim_name[20];
|
|
|
|
|
+ /*获取对方名字*/
|
|
|
|
|
+ struct msg_udp msg_data;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ if(!name)
|
|
|
|
|
+ {
|
|
|
|
|
+ pthread_mutex_lock(&lock1);
|
|
|
|
|
+ printf("对方名字:");
|
|
|
|
|
+ ret = scanf("%s", aim_name); //对方名字
|
|
|
|
|
+ pthread_mutex_unlock(&lock1);
|
|
|
|
|
+ //加入临时聊天对象
|
|
|
|
|
+ aim_name[19] = '\0';
|
|
|
|
|
+ bzero(&OTHER_UDP_ADDR, sizeof(struct sockaddr_in));
|
|
|
|
|
+ struct sockaddr_in *return_udp_addr = name_reurn_addr(1, aim_name);
|
|
|
|
|
+ if(return_udp_addr)
|
|
|
|
|
+ memcpy(&OTHER_UDP_ADDR, return_udp_addr, sizeof(struct sockaddr_in));
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ strcpy(aim_name, name);
|
|
|
|
|
+
|
|
|
|
|
+ printf("现对话为:%s\n", aim_name);
|
|
|
|
|
+ /*2.发送数据包*/
|
|
|
|
|
+ char buf[UDP_MAXSIZE+1];
|
|
|
|
|
+ bzero(buf, UDP_MAXSIZE+1);
|
|
|
|
|
+ if(!str)
|
|
|
|
|
+ {
|
|
|
|
|
+ pthread_mutex_lock(&lock1);
|
|
|
|
|
+ printf("请输入内容:\n");
|
|
|
|
|
+ ret = scanf("%s", buf);
|
|
|
|
|
+ pthread_mutex_unlock(&lock1);
|
|
|
|
|
+// char *s;
|
|
|
|
|
+// fflush(stdin);
|
|
|
|
|
+// s = fgets(buf, UDP_MAXSIZE, stdin);
|
|
|
|
|
+ //printf("用户[%s]输入:\n", MY_NAME);
|
|
|
|
|
+ }
|
|
|
|
|
+ else{
|
|
|
|
|
+ strcpy(buf, str);}
|
|
|
|
|
+ buf[UDP_MAXSIZE] = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (strlen(aim_name) > 0 && strlen(buf) > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ struct sockaddr_in *aim_udp_addr;
|
|
|
|
|
+ aim_udp_addr = name_reurn_addr(1, aim_name);
|
|
|
|
|
+
|
|
|
|
|
+ if (aim_udp_addr) //找到此用户,则发送;否则加入链表
|
|
|
|
|
+ {
|
|
|
|
|
+ //填写数据包信息
|
|
|
|
|
+ msg_data.type_udp = CHAT_ONE; //聊天类型
|
|
|
|
|
+ strcpy(msg_data.self_name, MY_NAME); //自己名字
|
|
|
|
|
+ strcpy(msg_data.aim_name, aim_name); //目标名字
|
|
|
|
|
+ msg_data.data_size = strlen(buf); //数据大小
|
|
|
|
|
+ buf[msg_data.data_size-1] = 0;
|
|
|
|
|
+ memcpy(msg_data.data, buf, msg_data.data_size); //数据
|
|
|
|
|
+ memcpy(&msg_data.self_addr_udp, &SELF_UDP_ADDR, sizeof(SELF_UDP_ADDR)); //自己地址
|
|
|
|
|
+ memcpy(&msg_data.aim_addr_udp, &pos2->cli_addr_udp, sizeof(pos2->cli_addr_udp));//目标地址
|
|
|
|
|
+
|
|
|
|
|
+ udp_addr_send_to(aim_udp_addr, &msg_data, sizeof(msg_data));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (strncmp(buf, "quit", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ msg_data.type_udp = NO_HANDLE; //不处理类型
|
|
|
|
|
+ play();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*群聊*/
|
|
|
|
|
+void toall(void)
|
|
|
|
|
+{
|
|
|
|
|
+ pr_debug("群聊\n");
|
|
|
|
|
+
|
|
|
|
|
+ char *s;
|
|
|
|
|
+ struct msg_udp msg_data;
|
|
|
|
|
+ /*2.发送数据包*/
|
|
|
|
|
+ char buf[UDP_MAXSIZE+1];
|
|
|
|
|
+ bzero(buf, UDP_MAXSIZE+1);
|
|
|
|
|
+ fflush(stdin);
|
|
|
|
|
+ s = fgets(buf, UDP_MAXSIZE, stdin);
|
|
|
|
|
+ //printf("用户[%s]输入:\n", MY_NAME);
|
|
|
|
|
+ buf[UDP_MAXSIZE] = 0;
|
|
|
|
|
+ if (strlen(buf) >= 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ struct list_head *n2 = NULL;
|
|
|
|
|
+ list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
|
|
|
|
|
+ {
|
|
|
|
|
+ pos2 = list_entry(p2, struct user_info, user_info_list);
|
|
|
|
|
+
|
|
|
|
|
+ char ip[16];
|
|
|
|
|
+ u_short port;
|
|
|
|
|
+
|
|
|
|
|
+ inet_ntop(AF_INET, (void *)&(pos2->cli_addr_udp.sin_addr.s_addr), ip, sizeof(ip));
|
|
|
|
|
+ port = ntohs(pos2->cli_addr_udp.sin_port);
|
|
|
|
|
+
|
|
|
|
|
+ //填写数据包信息
|
|
|
|
|
+ msg_data.type_udp = CHAT_ALL; //聊天类型
|
|
|
|
|
+ strcpy(msg_data.self_name, MY_NAME); //自己名字
|
|
|
|
|
+ strcpy(msg_data.aim_name, pos2->user_name); //目标名字
|
|
|
|
|
+ msg_data.data_size = strlen(buf); //数据大小
|
|
|
|
|
+ buf[msg_data.data_size-1] = 0;
|
|
|
|
|
+ memcpy(msg_data.data, buf, msg_data.data_size); //数据
|
|
|
|
|
+ memcpy(&msg_data.self_addr_udp, &SELF_UDP_ADDR, sizeof(SELF_UDP_ADDR)); //自己地址
|
|
|
|
|
+ memcpy(&msg_data.aim_addr_udp, &pos2->cli_addr_udp, sizeof(pos2->cli_addr_udp));//目标地址
|
|
|
|
|
+
|
|
|
|
|
+ udp_send_to(ip, port, &msg_data, sizeof(msg_data));
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (strncmp(buf, "quit", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ msg_data.type_udp = NO_HANDLE; //不处理类型
|
|
|
|
|
+ play();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*下线*/
|
|
|
|
|
+void lgout(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret =-1;
|
|
|
|
|
+ /*填写数据包信息*/
|
|
|
|
|
+ struct msg_udp msg_data;
|
|
|
|
|
+ msg_data.type_udp = OFFLINE; //退出类型
|
|
|
|
|
+ strcpy(msg_data.self_name, MY_NAME); //自己名字
|
|
|
|
|
+
|
|
|
|
|
+ /*发送*/
|
|
|
|
|
+ ret = udp_broad_send_to(BROADCAST_SEND_IP, BROADCAST_SEND_PORT_UDP, &msg_data, sizeof(msg_data)); //广播
|
|
|
|
|
+ IF_DOWN = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (ret != -1)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("下线成功!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*列表*/
|
|
|
|
|
+void list(void)
|
|
|
|
|
+{
|
|
|
|
|
+ pr_debug("列表\n");
|
|
|
|
|
+
|
|
|
|
|
+ struct servmsg_udp newmsg;
|
|
|
|
|
+ struct list_head *n2 = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ bzero(&newmsg.recvmsg.data, UDP_MAXSIZE+1);
|
|
|
|
|
+ list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
|
|
|
|
|
+ {
|
|
|
|
|
+ pos2 = list_entry(p2, struct user_info, user_info_list);
|
|
|
|
|
+
|
|
|
|
|
+ if(strlen((char *)&newmsg.recvmsg.data) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ sprintf(newmsg.recvmsg.data, "%s", pos2->user_name);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ sprintf(newmsg.recvmsg.data, "%s %s", newmsg.recvmsg.data, pos2->user_name);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ sprintf(newmsg.recvmsg.data, "%s%c", newmsg.recvmsg.data, '\n');
|
|
|
|
|
+ printf("用户列表:%s\n", newmsg.recvmsg.data);
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*=====================================以下TCP部分=====================================*/
|
|
|
|
|
+void *tcp_linked_list_manage(void *arg)
|
|
|
|
|
+{
|
|
|
|
|
+ sleep(2);
|
|
|
|
|
+ pr_debug("TCP链表管理\n");
|
|
|
|
|
+ int file_wrfd;
|
|
|
|
|
+ static int num_i=0, num_j=0;
|
|
|
|
|
+ static int sequence_i = 0; //数据顺序
|
|
|
|
|
+ size_t alto=0;
|
|
|
|
|
+ while (1)
|
|
|
|
|
+ {
|
|
|
|
|
+ if(num_j != J_TCP)
|
|
|
|
|
+ printf("** 下载:%d **\n", J_TCP);
|
|
|
|
|
+ num_i = I_TCP;
|
|
|
|
|
+ num_j = J_TCP;
|
|
|
|
|
+ //1.通过对小结构体的遍历,来获得大结构体的数据
|
|
|
|
|
+ struct list_head *n3 = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ list_for_each_safe(p3, n3, &tcp_data_head) //安全遍历聊天
|
|
|
|
|
+ {
|
|
|
|
|
+ pos3 = list_entry(p3, struct servmsg_tcp, servmsg_tcp_list);
|
|
|
|
|
+
|
|
|
|
|
+ char pr_data1[20];
|
|
|
|
|
+ memcpy(pr_data1, pos3->recvmsg.data,19);
|
|
|
|
|
+ printf("link->type:%d,data:%s\n",pos3->recvmsg.type_tcp, pr_data1);
|
|
|
|
|
+ //2.根据类型,处理数据
|
|
|
|
|
+ // printf("类型:%d,data=%s\n", pos1->recvmsg.type_udp, pos1->recvmsg.data);
|
|
|
|
|
+ switch (pos3->recvmsg.type_tcp)
|
|
|
|
|
+ {
|
|
|
|
|
+ case DOWN_IF: //是否下载
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("用户[%s]发来文件[%s],是否接收?(==y,==n)\n", addr_return_name(&pos3->recvmsg.self_addr_tcp), pos3->recvmsg.data);
|
|
|
|
|
+ char reply;
|
|
|
|
|
+
|
|
|
|
|
+ while(DOWN_IF_IN != 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("等待输入...\n");
|
|
|
|
|
+ sleep(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ reply = DATAIN[0];
|
|
|
|
|
+ DOWN_IF_IN = 0;
|
|
|
|
|
+ if (reply == 'y')
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("同意接受文件[%s]\n", pos3->recvmsg.data);
|
|
|
|
|
+
|
|
|
|
|
+ //填写资料
|
|
|
|
|
+ struct msg_tcp msg;
|
|
|
|
|
+ char *aim_name = addr_return_name(&pos3->recvmsg.self_addr_tcp);
|
|
|
|
|
+ if(aim_name)
|
|
|
|
|
+ {
|
|
|
|
|
+ msg.type_tcp = DOWN_YES; //类型
|
|
|
|
|
+ /* | | */
|
|
|
|
|
+ /* 让对方,进入下个选项 */
|
|
|
|
|
+ strcpy(msg.self_name, MY_NAME); //自己的名字
|
|
|
|
|
+ strcpy(msg.aim_name, aim_name); //目标名字
|
|
|
|
|
+ msg.data_size = strlen("*no*"); //数据大小0 ~ 65535
|
|
|
|
|
+ strcpy(msg.data, "*no*"); //数据
|
|
|
|
|
+ msg.data[TCP_MAXSIZE] = 0;
|
|
|
|
|
+ memcpy(&msg.self_addr_tcp, &SELF_TCP_ADDR, sizeof(struct sockaddr_in)); //自己tcp地址
|
|
|
|
|
+ memcpy(&msg.aim_addr_tcp, &pos3->recvmsg.self_addr_tcp, sizeof(struct sockaddr_in)); //目标地址
|
|
|
|
|
+
|
|
|
|
|
+ if(tcp_addr_send_to(&pos3->recvmsg.self_addr_tcp, &msg, sizeof(msg)))//发送TCP上传信息,文件名
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("DOWN_YES发送成功!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("DOWN_YES发送失败!\n");
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ printf("确认下载,填写资料有错\n");
|
|
|
|
|
+
|
|
|
|
|
+ I_TCP--;
|
|
|
|
|
+ list_del(&pos3->servmsg_tcp_list); //处理完后删除询问
|
|
|
|
|
+ free(pos3);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ /*====================================================*
|
|
|
|
|
+ 1.对方收到DOWN_YES, 发送DOWN_START, [等待...]
|
|
|
|
|
+ 2.自己收到DOWN_START, 建立文件, 发送DOWN_READY
|
|
|
|
|
+ 3.对方收到DOWN_READY, 发送DOWN_LOADING, [继续...]
|
|
|
|
|
+ 4.直到发送完
|
|
|
|
|
+ *====================================================*/
|
|
|
|
|
+ case DOWN_YES: //对方收到确认,上传过来
|
|
|
|
|
+ {
|
|
|
|
|
+ //读取文件,并发送
|
|
|
|
|
+ printf("收到确认,准备发送!\n");
|
|
|
|
|
+ struct sockaddr_in *cin = &pos3->recvmsg.self_addr_tcp;
|
|
|
|
|
+ char *way = UP_WAY;
|
|
|
|
|
+ struct msg_tcp msg;
|
|
|
|
|
+ char *aim_name = addr_return_name(cin);
|
|
|
|
|
+ if(aim_name)
|
|
|
|
|
+ {
|
|
|
|
|
+ msg.type_tcp = DOWN_START; //类型
|
|
|
|
|
+ strcpy(msg.self_name, MY_NAME); //自己的名字
|
|
|
|
|
+ strcpy(msg.aim_name, aim_name); //目标名字
|
|
|
|
|
+ memcpy(&msg.self_addr_tcp, &SELF_TCP_ADDR, sizeof(struct sockaddr_in)); //自己tcp地址
|
|
|
|
|
+ memcpy(&msg.aim_addr_tcp, cin, sizeof(struct sockaddr_in)); //目标地址
|
|
|
|
|
+
|
|
|
|
|
+ char *cut_p = NULL, *cut_q = NULL;
|
|
|
|
|
+ char copy_way[UDP_MAXSIZE+1];
|
|
|
|
|
+ strcpy(copy_way, way);
|
|
|
|
|
+ copy_way[UDP_MAXSIZE] = 0;
|
|
|
|
|
+ cut_p = strtok(copy_way, "/");
|
|
|
|
|
+ while(cut_p){
|
|
|
|
|
+ cut_q = cut_p;
|
|
|
|
|
+ cut_p = strtok(NULL, "/");
|
|
|
|
|
+ if(!cut_p)
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ msg.data_size = strlen(cut_q); //数据大小0 ~ 65535
|
|
|
|
|
+ bzero(msg.data, TCP_MAXSIZE+1);
|
|
|
|
|
+ strcpy(msg.data, cut_q); //数据
|
|
|
|
|
+ msg.data[TCP_MAXSIZE] = 0;
|
|
|
|
|
+ printf("%s,%s\n", cut_q,way);
|
|
|
|
|
+
|
|
|
|
|
+ tcp_info_check(cin);
|
|
|
|
|
+ if(tcp_addr_send_to(cin, &msg, sizeof(msg)))
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("DOWN_START发送成功!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("DOWN_START发送失败!\n");
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("read_file->aim_name 错误!\n");
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ I_TCP--;
|
|
|
|
|
+ list_del(&pos3->servmsg_tcp_list); //处理完后删除确认
|
|
|
|
|
+ free(pos3);
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case DOWN_NO: //拒绝下载
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case DOWN_START: //下载开始
|
|
|
|
|
+ {
|
|
|
|
|
+ /************************开始创建文件*****************************************************************************************/
|
|
|
|
|
+
|
|
|
|
|
+ char *file_name = pos3->recvmsg.data;
|
|
|
|
|
+
|
|
|
|
|
+ printf("[%s]下载开始!\n", file_name);
|
|
|
|
|
+
|
|
|
|
|
+ file_wrfd = open(file_name, O_RDWR | O_CREAT | O_APPEND, 0666);
|
|
|
|
|
+
|
|
|
|
|
+ struct down_info *newinfo;
|
|
|
|
|
+ newinfo = (struct down_info *)malloc(sizeof(struct down_info));
|
|
|
|
|
+ //1.添加信息
|
|
|
|
|
+ strcpy(newinfo->user_name, pos3->recvmsg.self_name); //用户名字
|
|
|
|
|
+ newinfo->file_wrfd = file_wrfd; //文件fd
|
|
|
|
|
+ memcpy(&newinfo->cli_addr_tcp, &pos3->recvmsg.self_addr_tcp, sizeof(struct sockaddr_in)); //客户端tcp地址
|
|
|
|
|
+
|
|
|
|
|
+ //2.加入链表
|
|
|
|
|
+ list_add_tail(&newinfo->down_info_list, &tcp_accept_head);
|
|
|
|
|
+ J_TCP++;
|
|
|
|
|
+
|
|
|
|
|
+ //3.收到DOWN_START,发送准备好了
|
|
|
|
|
+ struct msg_tcp msg;
|
|
|
|
|
+ char *aim_name = addr_return_name(&pos3->recvmsg.self_addr_tcp);
|
|
|
|
|
+ if(aim_name)
|
|
|
|
|
+ {
|
|
|
|
|
+ msg.type_tcp = DOWN_READY; //类型
|
|
|
|
|
+ /* | | */
|
|
|
|
|
+ /* 让对方,进入下个选项 */
|
|
|
|
|
+ strcpy(msg.self_name, MY_NAME); //自己的名字
|
|
|
|
|
+ strcpy(msg.aim_name, aim_name); //目标名字
|
|
|
|
|
+ msg.data_size = strlen("*no*"); //数据大小0 ~ 65535
|
|
|
|
|
+ strcpy(msg.data, "*no*"); //数据
|
|
|
|
|
+ msg.data[TCP_MAXSIZE] = 0;
|
|
|
|
|
+ memcpy(&msg.self_addr_tcp, &SELF_TCP_ADDR, sizeof(struct sockaddr_in)); //自己tcp地址
|
|
|
|
|
+ memcpy(&msg.aim_addr_tcp, &pos3->recvmsg.self_addr_tcp, sizeof(struct sockaddr_in)); //目标地址
|
|
|
|
|
+
|
|
|
|
|
+ if(tcp_addr_send_to(&pos3->recvmsg.self_addr_tcp, &msg, sizeof(msg)))//发送TCP上传信息,文件名
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("DOWN_READY发送成功!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("DOWN_READY发送失败!\n");
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ printf("确认下载,填写资料有错\n");
|
|
|
|
|
+
|
|
|
|
|
+ sequence_i = 0;
|
|
|
|
|
+ I_TCP--;
|
|
|
|
|
+ list_del(&pos3->servmsg_tcp_list); //处理完后删除开始下载
|
|
|
|
|
+ free(pos3);
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case DOWN_READY: //继续DOWN_YES的read_file上传
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("收到DOWN_READY\n");
|
|
|
|
|
+ DOWN_READY_IF = 1;
|
|
|
|
|
+ read_file(&pos3->recvmsg.self_addr_tcp, UP_WAY);
|
|
|
|
|
+
|
|
|
|
|
+ I_TCP--;
|
|
|
|
|
+ list_del(&pos3->servmsg_tcp_list); //处理完后删除开始下载
|
|
|
|
|
+ free(pos3);
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case DOWN_LOADING: //正在下载
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("正在下载!\n");
|
|
|
|
|
+ char pr_data[20];
|
|
|
|
|
+ memcpy(pr_data, pos3->recvmsg.data,19);
|
|
|
|
|
+ pr_debug("数据[%s]\n", pr_data);
|
|
|
|
|
+ printf("接受顺序:%d, 自定顺序:%d\n", pos3->recvmsg.data_sequence, sequence_i);
|
|
|
|
|
+
|
|
|
|
|
+ struct list_head *n4 = NULL;
|
|
|
|
|
+ list_for_each_safe(p4, n4, &tcp_accept_head) //安全遍历聊天
|
|
|
|
|
+ {
|
|
|
|
|
+ pos4 = list_entry(p4, struct down_info, down_info_list);
|
|
|
|
|
+ printf("user_name:%s,self_name:%s\n", pos4->user_name, pos3->recvmsg.self_name);
|
|
|
|
|
+ if (strncmp(pos4->user_name, pos3->recvmsg.self_name, strlen(pos3->recvmsg.self_name)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("数据顺序:%d, 数据大小:%d\n", pos3->recvmsg.data_sequence, pos3->recvmsg.data_size);
|
|
|
|
|
+ int ret;
|
|
|
|
|
+ if(pos3->recvmsg.data_sequence == sequence_i)
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ ret = write(pos4->file_wrfd, &pos3->recvmsg.data, pos3->recvmsg.data_size);
|
|
|
|
|
+ sequence_i++;
|
|
|
|
|
+ alto += pos3->recvmsg.data_size;
|
|
|
|
|
+
|
|
|
|
|
+ I_TCP--;
|
|
|
|
|
+ list_del(&pos3->servmsg_tcp_list); //处理完后删除正在下载
|
|
|
|
|
+ free(pos3);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case DOWN_END: //下载结束
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ printf("对方发送[%s]完成!\n", pos3->recvmsg.data);
|
|
|
|
|
+ printf("接收大小[%.2fk], 实际大小[%.2fk]\n", alto*1.0/1024, pos3->recvmsg.alto_size*1.0/1024);
|
|
|
|
|
+ struct list_head *n4 = NULL;
|
|
|
|
|
+ list_for_each_safe(p4, n4, &tcp_accept_head) //安全遍历聊天
|
|
|
|
|
+ {
|
|
|
|
|
+ pos4 = list_entry(p4, struct down_info, down_info_list);
|
|
|
|
|
+ if (strncmp(pos4->user_name, pos3->recvmsg.self_name, strlen(pos3->recvmsg.self_name)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ if(pos3->recvmsg.data_sequence == sequence_i)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("关闭文件[%d]\n", pos4->file_wrfd);
|
|
|
|
|
+ close(pos4->file_wrfd);
|
|
|
|
|
+ sequence_i = 0;
|
|
|
|
|
+ alto = 0;
|
|
|
|
|
+
|
|
|
|
|
+ I_TCP--;
|
|
|
|
|
+ free(pos3);
|
|
|
|
|
+ list_del(&pos3->servmsg_tcp_list); //处理完后删除下载结束
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ J_TCP--;
|
|
|
|
|
+ list_del(&pos4->down_info_list); //删除用户
|
|
|
|
|
+ free(pos4);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case UP_YES: //确认上传
|
|
|
|
|
+ {
|
|
|
|
|
+ /*
|
|
|
|
|
+ struct sockaddr_in cin;
|
|
|
|
|
+ char buf[TCP_MAXSIZE+1];
|
|
|
|
|
+ tcp_addr_recv_from(&SELF_TCP_ADDR, &cin, buf);
|
|
|
|
|
+ buf[TCP_MAXSIZE] = 0;
|
|
|
|
|
+ char *name=addr_return_name(&cin);
|
|
|
|
|
+ if(strncmp(buf, "ifdown|yes", strlen("ifdown|yes")))//ifdown|yes
|
|
|
|
|
+ printf("对方[%s],同意接收,请输入2,再回车", name);
|
|
|
|
|
+ else
|
|
|
|
|
+ printf("对方[%s],拒绝接收,返回请 --quit,继续请重新选择", name);
|
|
|
|
|
+ */
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case UP_NO: //拒绝上传
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ default:
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*TCP接收数据*/
|
|
|
|
|
+void *recv_tcp(void *arg)
|
|
|
|
|
+{
|
|
|
|
|
+ sleep(1);
|
|
|
|
|
+ pr_debug("TCP接收数据\n");
|
|
|
|
|
+ /*5.接收数据包*/
|
|
|
|
|
+ int ret = -1 ;
|
|
|
|
|
+ struct sockaddr_in cin; //发送者信息
|
|
|
|
|
+ struct msg_tcp msg; //收到他人发来的包
|
|
|
|
|
+
|
|
|
|
|
+ int tcp_addr_fd = tcp_addr_ini(&SELF_TCP_ADDR);
|
|
|
|
|
+ while (1)
|
|
|
|
|
+ {
|
|
|
|
|
+ bzero(&msg, sizeof(msg));
|
|
|
|
|
+ if(tcp_addr_fd)
|
|
|
|
|
+ {
|
|
|
|
|
+ ret = tcp_addr_recv_from(tcp_addr_fd, &cin, &msg);
|
|
|
|
|
+
|
|
|
|
|
+ printf("while体中recv\n");
|
|
|
|
|
+ tcp_info_check(&cin);
|
|
|
|
|
+
|
|
|
|
|
+ if (ret < 0) //真正出错了
|
|
|
|
|
+ {
|
|
|
|
|
+ perror("tcp_addr_recv_from");
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if(ret >0)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("recv->type:%d\n",msg.type_tcp);
|
|
|
|
|
+ struct servmsg_tcp *newmsg;
|
|
|
|
|
+ newmsg = (struct servmsg_tcp *)malloc(sizeof(struct servmsg_tcp));
|
|
|
|
|
+ //1.添加尾部
|
|
|
|
|
+ memcpy(&(newmsg->recvmsg), &msg, sizeof(msg)); //数据
|
|
|
|
|
+
|
|
|
|
|
+ //2.加入链表
|
|
|
|
|
+ list_add_tail(&newmsg->servmsg_tcp_list, &tcp_data_head);
|
|
|
|
|
+ I_TCP++;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*上传文件*/
|
|
|
|
|
+char read_file(struct sockaddr_in *cin, char *way)
|
|
|
|
|
+{
|
|
|
|
|
+ int file_rdfd;
|
|
|
|
|
+ char buf[TCP_MAXSIZE+1];
|
|
|
|
|
+ int sequence_i = 0;
|
|
|
|
|
+ struct msg_tcp msg;
|
|
|
|
|
+ size_t size, alto, real_num=0;
|
|
|
|
|
+
|
|
|
|
|
+ while(!DOWN_READY_IF)
|
|
|
|
|
+ {
|
|
|
|
|
+ sleep(1);
|
|
|
|
|
+ printf("等待DOWN_READY回复\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ DOWN_READY_IF = 0;
|
|
|
|
|
+
|
|
|
|
|
+ file_rdfd = open(way, O_RDONLY, 0644);
|
|
|
|
|
+ alto = size = lseek(file_rdfd, 0L, SEEK_END) - lseek(file_rdfd, 0L, SEEK_SET);
|
|
|
|
|
+ if (alto == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("空文件!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ while (size >= TCP_MAXSIZE) //文件大于5k,则每8k上传
|
|
|
|
|
+ {
|
|
|
|
|
+ bzero(buf, TCP_MAXSIZE+1);
|
|
|
|
|
+ lseek(file_rdfd, 0L, real_num);
|
|
|
|
|
+ if (read(file_rdfd, buf, TCP_MAXSIZE) > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ msg.type_tcp = DOWN_LOADING; //类型
|
|
|
|
|
+ strcpy(msg.self_name, MY_NAME); //自己的名字
|
|
|
|
|
+ char *aim_name = addr_return_name(cin);
|
|
|
|
|
+ if(aim_name)
|
|
|
|
|
+ strcpy(msg.aim_name, aim_name); //目标名字
|
|
|
|
|
+ msg.data_size = TCP_MAXSIZE; //数据大小0 ~ 65535
|
|
|
|
|
+ msg.data_sequence = sequence_i;
|
|
|
|
|
+ bzero(msg.data, TCP_MAXSIZE+1);
|
|
|
|
|
+ memcpy(msg.data, buf, TCP_MAXSIZE); //数据
|
|
|
|
|
+ msg.data[TCP_MAXSIZE] = 0;
|
|
|
|
|
+ if (tcp_addr_send_to(cin, &msg, sizeof(msg)))
|
|
|
|
|
+ {
|
|
|
|
|
+ sequence_i++;
|
|
|
|
|
+ real_num += TCP_MAXSIZE;
|
|
|
|
|
+ size -= TCP_MAXSIZE;
|
|
|
|
|
+ printf("上传 >5k %.2f%%\n", real_num*100.0/alto);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("读取文件失败1\n");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ while (size < TCP_MAXSIZE && size > 0) //小于5k,则按size大小上传
|
|
|
|
|
+ {
|
|
|
|
|
+ bzero(buf, TCP_MAXSIZE+1);
|
|
|
|
|
+ lseek(file_rdfd, 0L, real_num);
|
|
|
|
|
+ if (read(file_rdfd, buf, size) != -1)
|
|
|
|
|
+ {
|
|
|
|
|
+ msg.type_tcp = DOWN_LOADING; //类型
|
|
|
|
|
+ strcpy(msg.self_name, MY_NAME); //自己的名字
|
|
|
|
|
+ char *aim_name = addr_return_name(cin);
|
|
|
|
|
+ if(aim_name)
|
|
|
|
|
+ strcpy(msg.aim_name, aim_name); //目标名字
|
|
|
|
|
+ msg.data_size = size; //数据大小0 ~ 65535
|
|
|
|
|
+ msg.data_sequence = sequence_i;
|
|
|
|
|
+ bzero(msg.data, TCP_MAXSIZE+1);
|
|
|
|
|
+ memcpy(msg.data, buf, size); //数据
|
|
|
|
|
+ msg.data[TCP_MAXSIZE] = 0;
|
|
|
|
|
+ if (tcp_addr_send_to(cin, &msg, sizeof(msg)))
|
|
|
|
|
+ {
|
|
|
|
|
+ sequence_i++;
|
|
|
|
|
+ real_num = real_num + size;
|
|
|
|
|
+ size = size - size;
|
|
|
|
|
+ printf("上传 <5k %.2f%%\n", real_num*100.0/alto);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("读取文件失败2\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ msg.type_tcp = DOWN_END; //类型
|
|
|
|
|
+ strcpy(msg.self_name, MY_NAME); //自己的名字
|
|
|
|
|
+ char *aim_name = addr_return_name(cin);
|
|
|
|
|
+ if(aim_name)
|
|
|
|
|
+ strcpy(msg.aim_name, aim_name); //目标名字
|
|
|
|
|
+ msg.data_size = strlen("upend"); //数据大小0 ~ 65535
|
|
|
|
|
+ msg.data_sequence = sequence_i;
|
|
|
|
|
+ msg.alto_size = alto;
|
|
|
|
|
+ bzero(msg.data, TCP_MAXSIZE+1);
|
|
|
|
|
+ strcpy(msg.data, "upend"); //数据
|
|
|
|
|
+ msg.data[TCP_MAXSIZE] = 0;
|
|
|
|
|
+ if (tcp_addr_send_to(cin, &msg, sizeof(msg))) //上传完成
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("上传完成!\n发送大小[%.2fk], 实际大小[%.2fk]\n", alto*1.0/1024, real_num*1.0/1024);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ printf("上传失败!\n");
|
|
|
|
|
+
|
|
|
|
|
+ close(file_rdfd);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*上传*/
|
|
|
|
|
+void up(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret = -1;
|
|
|
|
|
+ ret = system("clear");
|
|
|
|
|
+ printf("this is UPLOAD\n");
|
|
|
|
|
+ printf("=============上传帮助=============\n");
|
|
|
|
|
+ printf("== 1.默认本目录+【文件名】 ==\n");
|
|
|
|
|
+ printf("== 2.【完整文件路径】 ==\n");
|
|
|
|
|
+ printf("== 3.查看上传文件列表 ==\n");
|
|
|
|
|
+ printf("== 4.退出 ==\n");
|
|
|
|
|
+ printf("==================================\n");
|
|
|
|
|
+
|
|
|
|
|
+ up_ord();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void up_ord(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret = -1;
|
|
|
|
|
+ char *s;
|
|
|
|
|
+ char ord[10];
|
|
|
|
|
+ pthread_mutex_lock(&lock1);
|
|
|
|
|
+ printf("选择命令:");
|
|
|
|
|
+ ret = scanf("%s", ord);
|
|
|
|
|
+ pthread_mutex_unlock(&lock1);
|
|
|
|
|
+ if (strncmp(ord, "clear", 5) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ up();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (!((strlen(ord) == 1) && (ord[0] == '1' || '2' || '3' || '4')))
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("输入选项错误,进入命令界面!\n");
|
|
|
|
|
+ play();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ switch (atoi(ord))
|
|
|
|
|
+ {
|
|
|
|
|
+ char file_name[20];
|
|
|
|
|
+ char aim_name[20];
|
|
|
|
|
+ static struct sockaddr_in *aim_addr_udp = NULL;
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项1\n");
|
|
|
|
|
+ s = getcwd(UP_WAY, sizeof(UP_WAY));
|
|
|
|
|
+ pthread_mutex_lock(&lock1);
|
|
|
|
|
+ printf("当前目录下,请输入文件名:\n");
|
|
|
|
|
+ ret = scanf("%s", file_name);
|
|
|
|
|
+ pthread_mutex_unlock(&lock1);
|
|
|
|
|
+ sprintf(UP_WAY,"%s/%s", UP_WAY, file_name);
|
|
|
|
|
+ if (access(UP_WAY, F_OK | R_OK) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("[%s]存在!\n", file_name);
|
|
|
|
|
+ pthread_mutex_lock(&lock1);
|
|
|
|
|
+ printf("接收者名字:\n");
|
|
|
|
|
+ ret = scanf("%s", aim_name);
|
|
|
|
|
+ pthread_mutex_unlock(&lock1);
|
|
|
|
|
+
|
|
|
|
|
+ struct sockaddr_in *aim_addr_tcp = name_reurn_addr(2, aim_name);
|
|
|
|
|
+
|
|
|
|
|
+ //填写资料
|
|
|
|
|
+ struct msg_tcp msg;
|
|
|
|
|
+ if(aim_addr_tcp)
|
|
|
|
|
+ {
|
|
|
|
|
+ msg.type_tcp = DOWN_IF; //类型
|
|
|
|
|
+ strcpy(msg.self_name, MY_NAME); //自己的名字
|
|
|
|
|
+ strcpy(msg.aim_name, aim_name); //目标名字
|
|
|
|
|
+ msg.data_size = strlen(file_name); //数据大小0 ~ 65535
|
|
|
|
|
+ strcpy(msg.data, file_name); //数据
|
|
|
|
|
+ msg.data[TCP_MAXSIZE] = 0;
|
|
|
|
|
+ memcpy(&msg.self_addr_tcp, &SELF_TCP_ADDR, sizeof(struct sockaddr_in)); //自己tcp地址
|
|
|
|
|
+ memcpy(&msg.aim_addr_tcp, aim_addr_tcp, sizeof(struct sockaddr_in)); //目标地址
|
|
|
|
|
+
|
|
|
|
|
+ tcp_addr_send_to(aim_addr_tcp, &msg, sizeof(msg));//发送TCP上传信息,文件名
|
|
|
|
|
+ printf("上传请求成功!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ printf("上传,填写资料有错\n");
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项2\n");
|
|
|
|
|
+ s = fgets(UP_WAY, sizeof(UP_WAY), stdin);
|
|
|
|
|
+ if (access(UP_WAY, F_OK | R_OK) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ char *cut_p;
|
|
|
|
|
+ cut_p = strtok(UP_WAY, "/");
|
|
|
|
|
+ while (cut_p)
|
|
|
|
|
+ {
|
|
|
|
|
+ cut_p = strtok(NULL, "/");
|
|
|
|
|
+ }
|
|
|
|
|
+ pr_debug("[%s]存在!\n", cut_p);
|
|
|
|
|
+ char file_info[30];
|
|
|
|
|
+ sprintf(file_info, "if_down%s", cut_p);
|
|
|
|
|
+ tcp_send_to(OTHER_IP, OTHER_PORT_TCP, file_info, sizeof(file_info));//发送TCP上传信息,文件名
|
|
|
|
|
+
|
|
|
|
|
+ /*填写数据包信息*/
|
|
|
|
|
+ struct msg_udp msg_data;
|
|
|
|
|
+ msg_data.type_udp = UPLOAD; //聊天类型
|
|
|
|
|
+ strcpy(msg_data.self_name, MY_NAME); //自己名字
|
|
|
|
|
+ sprintf(msg_data.data, "upstart_%s", cut_p); //发送UDP上传信息,文件名
|
|
|
|
|
+ udp_send_to(OTHER_IP, OTHER_PORT_TCP, &msg_data, sizeof(msg_data));//发送UDP上传信息,文件名
|
|
|
|
|
+ if(aim_addr_udp)
|
|
|
|
|
+ read_file(aim_addr_udp, UP_WAY);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项3\n");
|
|
|
|
|
+ //发送下载列表信息
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 4:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项4\n");
|
|
|
|
|
+ play();
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*下载*/
|
|
|
|
|
+void down(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret = -1;
|
|
|
|
|
+ char *s;
|
|
|
|
|
+ ret = system("clear");
|
|
|
|
|
+ printf("this is DOWNLOAD\n");
|
|
|
|
|
+ printf("==============下载帮助==============\n");
|
|
|
|
|
+ printf("== 1.默认本目录,为下载路径 ==\n");
|
|
|
|
|
+ printf("== 2.输入下载文件路径 ==\n");
|
|
|
|
|
+ printf("== 3.查看下载文件列表 ==\n");
|
|
|
|
|
+ printf("== 4.开始下载 ==\n");
|
|
|
|
|
+ printf("== 5.退出 ==\n");
|
|
|
|
|
+ printf("====================================\n");
|
|
|
|
|
+
|
|
|
|
|
+ char ord[10];
|
|
|
|
|
+ pthread_mutex_lock(&lock1);
|
|
|
|
|
+ printf("命令:");
|
|
|
|
|
+ ret = scanf("%s", ord);
|
|
|
|
|
+ pthread_mutex_unlock(&lock1);
|
|
|
|
|
+ if (!((strlen(ord) == 1) && (ord[0] == '1' || '2' || '3' || '4')))
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("输入选项错误,进入命令界面!\n");
|
|
|
|
|
+ play();
|
|
|
|
|
+ }
|
|
|
|
|
+ switch (atoi(ord))
|
|
|
|
|
+ {
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项1\n");
|
|
|
|
|
+ s = getcwd(DOWN_WAY, sizeof(DOWN_WAY));
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项2\n");
|
|
|
|
|
+ s = fgets(DOWN_WAY, sizeof(DOWN_WAY), stdin);
|
|
|
|
|
+ if (access(DOWN_WAY, F_OK | R_OK) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("目录存在,可以下载!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ char ord[50] = "mkdir -p ";
|
|
|
|
|
+ sprintf(ord, "%s%s", ord, DOWN_WAY);
|
|
|
|
|
+ ret = system(DOWN_WAY);
|
|
|
|
|
+ pr_debug("目录不存在,创建成功,可以下载!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项3\n");
|
|
|
|
|
+ //发送下载列表信息
|
|
|
|
|
+
|
|
|
|
|
+ /*TCP地址信息*/
|
|
|
|
|
+ struct msg_udp usron;
|
|
|
|
|
+ usron.type_udp = DOWNLOAD; //上线类型
|
|
|
|
|
+ strcpy(usron.self_name, MY_NAME); //自己名字
|
|
|
|
|
+ strcpy(usron.data, "list"); //list标识
|
|
|
|
|
+ usron.aim_addr_udp.sin_family = AF_INET; //他人地址
|
|
|
|
|
+ usron.aim_addr_udp.sin_port = htons(OTHER_PORT_UDP); //UDP接收列表
|
|
|
|
|
+ usron.aim_addr_udp.sin_addr.s_addr = inet_addr(OTHER_IP);
|
|
|
|
|
+ bzero(usron.aim_addr_udp.sin_zero, 8);
|
|
|
|
|
+
|
|
|
|
|
+ udp_send_to(OTHER_IP, OTHER_PORT_TCP, &usron, sizeof(usron));//发送UDP上传信息,文件名
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 4:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项4\n");
|
|
|
|
|
+ //发送下载列表信息
|
|
|
|
|
+ /*TCP地址信息*/
|
|
|
|
|
+ struct msg_udp usron;
|
|
|
|
|
+ usron.type_udp = DOWNLOAD; //上线类型
|
|
|
|
|
+ strcpy(usron.self_name, MY_NAME); //自己名字
|
|
|
|
|
+ char file_name[30];
|
|
|
|
|
+ printf("请输入文件名:");
|
|
|
|
|
+ ret = scanf("%s", file_name);
|
|
|
|
|
+ sprintf(usron.data, "start:%s", file_name);//start标识
|
|
|
|
|
+ usron.aim_addr_udp.sin_family = AF_INET; //他人地址
|
|
|
|
|
+ usron.aim_addr_udp.sin_port = htons(OTHER_PORT_TCP); //TCP接收文件
|
|
|
|
|
+ usron.aim_addr_udp.sin_addr.s_addr = inet_addr(OTHER_IP);
|
|
|
|
|
+ bzero(usron.aim_addr_udp.sin_zero, 8);
|
|
|
|
|
+
|
|
|
|
|
+ udp_send_to(OTHER_IP, OTHER_PORT_TCP, &usron, sizeof(usron));//发送UDP上传信息,文件名
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 5:
|
|
|
|
|
+ {
|
|
|
|
|
+ pr_debug("进入选项4\n");
|
|
|
|
|
+ play();
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+struct sockaddr_in *name_reurn_addr(int type, char *aim_name)
|
|
|
|
|
+{
|
|
|
|
|
+ int finded_name = NO_FIND;
|
|
|
|
|
+ struct list_head *n2 = NULL;
|
|
|
|
|
+ list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
|
|
|
|
|
+ {
|
|
|
|
|
+ pos2 = list_entry(p2, struct user_info, user_info_list);
|
|
|
|
|
+ if (strncmp(aim_name, pos2->user_name, strlen(pos2->user_name)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ finded_name = HAVE_FIND;
|
|
|
|
|
+ if(type == 1)
|
|
|
|
|
+ return &pos2->cli_addr_udp;
|
|
|
|
|
+ else if(type == 2)
|
|
|
|
|
+ return &pos2->cli_addr_tcp;
|
|
|
|
|
+ else
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (finded_name != HAVE_FIND) //找到此用户,则发送;否则加入链表
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("未找到[%s]此用户\n", aim_name);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+char *addr_return_name(struct sockaddr_in *addr)
|
|
|
|
|
+{
|
|
|
|
|
+ int finded_name = NO_FIND;
|
|
|
|
|
+ struct list_head *n2 = NULL;
|
|
|
|
|
+ list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
|
|
|
|
|
+ {
|
|
|
|
|
+ pos2 = list_entry(p2, struct user_info, user_info_list);
|
|
|
|
|
+ if (memcmp(&pos2->cli_addr_tcp.sin_addr, &addr->sin_addr, sizeof(struct in_addr)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ finded_name = HAVE_FIND;
|
|
|
|
|
+ return pos2->user_name;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (finded_name != HAVE_FIND) //找到此用户,则发送;否则加入链表
|
|
|
|
|
+ {
|
|
|
|
|
+ char ip[16];
|
|
|
|
|
+ u_short port;
|
|
|
|
|
+ inet_ntop(AF_INET, (void *)&(addr->sin_addr.s_addr), ip, sizeof(ip));
|
|
|
|
|
+ port = ntohs(addr->sin_port);
|
|
|
|
|
+ printf("未找到[%s:%d]此用户\n", ip, port);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*=====================================以上TCP部分=====================================*/
|
|
|
|
|
+
|
|
|
|
|
+/*帮助*/
|
|
|
|
|
+void help(void)
|
|
|
|
|
+{
|
|
|
|
|
+ pr_debug("帮助\n");
|
|
|
|
|
+
|
|
|
|
|
+ int ret =-1;
|
|
|
|
|
+ ret = system("clear");
|
|
|
|
|
+ printf("this is Help\n");
|
|
|
|
|
+ printf("=================帮助=================\n");
|
|
|
|
|
+ printf("== 1.命令格式:“--” + “命令” ==\n");
|
|
|
|
|
+ printf("== 2.聊天时,使用quit退出聊天 ==\n");
|
|
|
|
|
+ printf("== 3.使用clear回到,命令界面 ==\n");
|
|
|
|
|
+ printf("== 4.如果ctrl+c,则下线,程序结束 ==\n");
|
|
|
|
|
+ printf("== 5.输入quit,退出帮助界面 ==\n");
|
|
|
|
|
+ printf("======================================\n");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*判断(命令)*/
|
|
|
|
|
+void judge(char *ord)
|
|
|
|
|
+{
|
|
|
|
|
+ if(!ord);
|
|
|
|
|
+ else if (strncmp(ord, "help", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ help();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "clear", 5) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ play();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "talk", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ talk(NULL, NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "down", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ down();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "list", 4) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ list();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "lgout", 5) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ lgout();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "toall", 5) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ toall();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "up", 2) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ up();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("没有这个命令!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*显示*/
|
|
|
|
|
+void play(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret = -1;
|
|
|
|
|
+ ret = system("clear");
|
|
|
|
|
+ printf("this is LAN chat\n");
|
|
|
|
|
+ printf("=================命令===============\n");
|
|
|
|
|
+ printf("== --help 帮助 --lgout 下线 ==\n");
|
|
|
|
|
+ printf("== --talk 私聊 --toall 群聊 ==\n");
|
|
|
|
|
+ printf("== --down 下载 --up 上传 ==\n");
|
|
|
|
|
+ printf("== --list 列表 --clear 清屏 ==\n");
|
|
|
|
|
+ printf("====================================\n");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*命令 或 聊天*/
|
|
|
|
|
+void order_or_chat(char *ord)
|
|
|
|
|
+{
|
|
|
|
|
+ char ret;
|
|
|
|
|
+ char *cut_p;
|
|
|
|
|
+ char *aim_name;
|
|
|
|
|
+ char new_ord[UDP_MAXSIZE+1];
|
|
|
|
|
+
|
|
|
|
|
+ while(IF_ORD_IN == 0);
|
|
|
|
|
+ if (!ord) //为空,输入
|
|
|
|
|
+ {
|
|
|
|
|
+ bzero(new_ord, UDP_MAXSIZE+1);
|
|
|
|
|
+ pthread_mutex_lock(&lock1);
|
|
|
|
|
+ printf("请输入命令或消息:\n");
|
|
|
|
|
+ ret = scanf("%s", new_ord);
|
|
|
|
|
+ pthread_mutex_unlock(&lock1);
|
|
|
|
|
+ order_or_chat(new_ord);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "--", 2) == 0) //不为空,直接去掉--
|
|
|
|
|
+ {
|
|
|
|
|
+ cut_p = strtok(ord, "--");
|
|
|
|
|
+ if (cut_p)
|
|
|
|
|
+ {
|
|
|
|
|
+ judge(cut_p);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "++", 2) == 0) //不为空,直接去掉--
|
|
|
|
|
+ {
|
|
|
|
|
+ cut_p = strtok(ord, "++");
|
|
|
|
|
+ if (cut_p && cut_p[0] == 'y')
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("cut_p:%s\n", cut_p);
|
|
|
|
|
+ strcpy(DATAIN, cut_p);
|
|
|
|
|
+ CHANGE_AIM_IF_IN = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (strncmp(ord, "==", 2) == 0) //不为空,直接去掉--
|
|
|
|
|
+ {
|
|
|
|
|
+ cut_p = strtok(ord, "==");
|
|
|
|
|
+ if (cut_p && cut_p[0] == 'y')
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("cut_p:%s\n", cut_p);
|
|
|
|
|
+ strcpy(DATAIN, cut_p);
|
|
|
|
|
+ DOWN_IF_IN = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ aim_name = addr_return_name(&OTHER_UDP_ADDR);
|
|
|
|
|
+ if(aim_name && ord) //找到用户
|
|
|
|
|
+ {
|
|
|
|
|
+ talk(aim_name, ord);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ send_online_info();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ order_or_chat(NULL);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void nametrue(int argc, char *argv[])
|
|
|
|
|
+{
|
|
|
|
|
+ if (argc >= 2)
|
|
|
|
|
+ {
|
|
|
|
|
+ memcpy(MY_NAME, argv[1], strlen(argv[1])); //自己名字
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ strcpy(MY_NAME, "xx");
|
|
|
|
|
+ printf("please input your name!\n");
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void func(int signo)
|
|
|
|
|
+{
|
|
|
|
|
+ lgout();
|
|
|
|
|
+ pr_debug("\n[%s]退出!\n", MY_NAME);
|
|
|
|
|
+ exit(1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*填写本机绑定IP、端口号*/
|
|
|
|
|
+char info_udp_tcp(void)
|
|
|
|
|
+{
|
|
|
|
|
+ SELF_UDP_ADDR.sin_family = AF_INET; //自己UDP地址
|
|
|
|
|
+ SELF_UDP_ADDR.sin_port = htons(SELF_PORT_UDP);
|
|
|
|
|
+ SELF_UDP_ADDR.sin_addr.s_addr = inet_addr(SELF_IP);
|
|
|
|
|
+ bzero(SELF_UDP_ADDR.sin_zero, 8);
|
|
|
|
|
+
|
|
|
|
|
+ SELF_TCP_ADDR.sin_family = AF_INET; //自己TCP地址
|
|
|
|
|
+ SELF_TCP_ADDR.sin_port = htons(SELF_PORT_TCP);
|
|
|
|
|
+ SELF_TCP_ADDR.sin_addr.s_addr = inet_addr(SELF_IP);
|
|
|
|
|
+ bzero(SELF_TCP_ADDR.sin_zero, 8);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*登入线程*/
|
|
|
|
|
+void *loading_thread(void *arg)
|
|
|
|
|
+{
|
|
|
|
|
+ play(); //显示界面
|
|
|
|
|
+ info_udp_tcp(); //tcp udp 信息IP端口绑定
|
|
|
|
|
+ loading_udp(); //上线
|
|
|
|
|
+ sleep(3);
|
|
|
|
|
+ order_or_chat(NULL); //命令判断->进入各功能
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+int main(int argc, char *argv[])
|
|
|
|
|
+{
|
|
|
|
|
+ nametrue(argc, argv); //处理输入名字
|
|
|
|
|
+ pr_debug("昵称:%s\n", MY_NAME); //测试名字
|
|
|
|
|
+ signal(SIGINT, func); //注册Ctrl + C
|
|
|
|
|
+
|
|
|
|
|
+ pthread_mutex_init(&lock1, NULL); //初始化锁1
|
|
|
|
|
+
|
|
|
|
|
+ pthread_t tid1; //登入、命令处理
|
|
|
|
|
+ pthread_t tid2; //UDP接收线程,聊天
|
|
|
|
|
+ pthread_t tid3; //UDP广播接收线程,上线
|
|
|
|
|
+ pthread_t tid4; //TCP接收线程,文件传送
|
|
|
|
|
+ pthread_t tid5; //循环遍历,结构体处理,类型UDP
|
|
|
|
|
+ pthread_t tid6; //循环遍历,结构体处理,类型TCP
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ pthread_create(&tid1, NULL, loading_thread, NULL);
|
|
|
|
|
+ pthread_create(&tid2, NULL, recv_udp, NULL);
|
|
|
|
|
+ pthread_create(&tid3, NULL, recv_broad_udp, NULL);
|
|
|
|
|
+ pthread_create(&tid4, NULL, recv_tcp, NULL);
|
|
|
|
|
+ pthread_create(&tid5, NULL, udp_linked_list_manage, NULL);
|
|
|
|
|
+ pthread_create(&tid6, NULL, tcp_linked_list_manage, NULL);
|
|
|
|
|
+
|
|
|
|
|
+ pthread_join(tid1, NULL);
|
|
|
|
|
+ pthread_join(tid2, NULL);
|
|
|
|
|
+ pthread_join(tid3, NULL);
|
|
|
|
|
+ pthread_join(tid4, NULL);
|
|
|
|
|
+ pthread_join(tid5, NULL);
|
|
|
|
|
+ pthread_join(tid6, NULL);
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|