| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710 |
- #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;
- }
|