2.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710
  1. #include "include/tcp.h"
  2. #include "include/udp.h"
  3. #include "include/mychat.h"
  4. #if 1
  5. #define SELF_PORT_UDP 5002
  6. #define SELF_PORT_TCP 5003
  7. #define SELF_IP "192.168.188.136" //自己IP
  8. #define OTHER_PORT_UDP 5004
  9. #define OTHER_PORT_TCP 5005
  10. #define OTHER_IP "192.168.188.136" //他人IP
  11. #define BROADCAST_SEND_PORT_UDP 5200
  12. #define BROADCAST_RECV_PORT_UDP 5300
  13. #define BROADCAST_RECV_IP INADDR_ANY //广播IP
  14. #define BROADCAST_SEND_IP INADDR_BROADCAST //广播IP
  15. #else
  16. #define OTHER_PORT_UDP 5002
  17. #define OTHER_PORT_TCP 5003
  18. #define OTHER_IP "192.168.188.136" //自己IP
  19. #define SELF_PORT_UDP 5004
  20. #define SELF_PORT_TCP 5005
  21. #define SELF_IP "192.168.188.136" //他人IP
  22. #define BROADCAST_RECV_PORT_UDP 5200
  23. #define BROADCAST_SEND_PORT_UDP 5300
  24. #define BROADCAST_RECV_IP INADDR_ANY //广播IP
  25. #define BROADCAST_SEND_IP INADDR_BROADCAST //广播IP
  26. #endif
  27. #define NO_FIND 0
  28. #define HAVE_FIND 1
  29. LIST_HEAD(udp_data_head); //聊天数据
  30. struct list_head *p1 = NULL;
  31. struct servmsg_udp *pos1 = NULL;
  32. LIST_HEAD(udp_online_head); //用户列表
  33. struct list_head *p2 = NULL;
  34. struct user_info *pos2 = NULL;
  35. LIST_HEAD(tcp_data_head); //下载数据
  36. struct list_head *p3 = NULL;
  37. struct servmsg_tcp *pos3 = NULL;
  38. LIST_HEAD(tcp_accept_head); //下载允许用户
  39. struct list_head *p4 = NULL;
  40. struct down_info *pos4 = NULL;
  41. int I_UDP=0; //聊天数
  42. int J_UDP=0; //上线数
  43. int I_TCP=0; //文件数
  44. int J_TCP=0; //下载数
  45. pthread_mutex_t lock1;
  46. char DATAIN[UDP_MAXSIZE+1]; //输入的内容
  47. int DOWN_IF_IN = 0; //下载确认输入
  48. int CHANGE_AIM_IF_IN =0; //改变对象选择输入
  49. int IF_CHAT_IN = 1; //等待聊天输入完成
  50. int IF_ORD_IN = 1; //等待命令输入完成
  51. int DOWN_READY_IF = 0; //下载准备
  52. int IF_DOWN = 0; //0已经下线,1已经上线
  53. char UP_WAY[50]; //上传路径
  54. char DOWN_WAY[50]; //下载路径
  55. char DOWN_NAME[20]; //下载文件名
  56. char MY_NAME[20]; //自己的名字
  57. struct sockaddr_in SELF_UDP_ADDR; //自己UDP信息,上线信息
  58. struct sockaddr_in SELF_TCP_ADDR; //自己TCP信息,上线信息
  59. //char AIM_NAME[20]; //目标的名字
  60. struct sockaddr_in OTHER_UDP_ADDR;//他人UDP信息,临时通讯地址
  61. struct sockaddr_in OTHER_TCP_ADDR;//他人TCP信息,临时通讯地址
  62. /**************************************以下UDP部分*******************************************/
  63. /*UDP发送数据*/
  64. void play(void);
  65. void up_ord(void);
  66. void order_or_chat(char *ord);
  67. char read_file(struct sockaddr_in *cin, char *way);
  68. char *addr_return_name(struct sockaddr_in *addr);
  69. struct sockaddr_in *name_reurn_addr(int type, char *aim_name);
  70. int send_online_info(void)
  71. {
  72. /*上线信息*/
  73. struct msg_udp usron;
  74. //填写数据包信息
  75. usron.type_udp = LOG_IN; //聊天类型
  76. strcpy(usron.self_name, MY_NAME); //自己名字
  77. strcpy(usron.aim_name, "*no*"); //目标名字
  78. usron.data_size = strlen("*no*"); //消息大小
  79. strcpy(usron.data, "*no*"); //数据
  80. memcpy(&usron.self_addr_udp, &SELF_UDP_ADDR, sizeof(SELF_UDP_ADDR)); //自己UDP地址
  81. memcpy(&usron.self_addr_tcp, &SELF_TCP_ADDR, sizeof(SELF_TCP_ADDR)); //自己TCP地址
  82. strcpy((char *)&usron.aim_addr_udp, "*no*"); //目标地址
  83. int ret = -1;
  84. ret = udp_broad_send_to(BROADCAST_SEND_IP, BROADCAST_SEND_PORT_UDP, &usron, sizeof(usron)); //广播IP 255
  85. if(ret == -1)
  86. {
  87. pr_debug("广播失败!\n");
  88. return -1;
  89. }
  90. return 0;
  91. }
  92. /*UDP登入*/
  93. void loading_udp(void)
  94. {
  95. int ret = -1;
  96. if (IF_DOWN == 0)
  97. {
  98. do
  99. {
  100. ret = send_online_info();
  101. pr_debug("正在登入中...\n");
  102. }
  103. while (ret != 0);
  104. IF_DOWN = 1;
  105. }
  106. }
  107. int udp_linked_list_add(struct msg_udp *msg)
  108. {
  109. switch (msg->type_udp)
  110. {
  111. case LOG_IN: //登入
  112. {
  113. char *name_p = msg->self_name;
  114. if(!(name_p && name_p > 0 && strlen(name_p) < 20 && strncmp(name_p, MY_NAME, strlen(MY_NAME)) != 0))
  115. break;
  116. int finded_name = NO_FIND;
  117. struct list_head *n2 = NULL;
  118. list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
  119. {
  120. pos2 = list_entry(p2, struct user_info, user_info_list);
  121. if (strncmp(msg->self_name, pos2->user_name, strlen(pos2->user_name)) == 0)
  122. {
  123. finded_name = HAVE_FIND;
  124. }
  125. }
  126. if (finded_name != HAVE_FIND) //没有找到此用户,则加入
  127. {
  128. struct user_info *newmsg;
  129. newmsg = (struct user_info *)malloc(sizeof(struct user_info));
  130. //1.填写IP与端口
  131. memcpy(&(newmsg->user_name), msg->self_name, sizeof(msg->self_name)); //客户名
  132. (newmsg->id)++; //id
  133. memcpy(&(newmsg->cli_addr_udp), &msg->self_addr_udp, sizeof(msg->self_addr_udp)); //UDP IP地址与端口号
  134. memcpy(&(newmsg->cli_addr_tcp), &msg->self_addr_tcp, sizeof(msg->self_addr_tcp)); //TCP IP地址与端口号
  135. //2.加入链表
  136. list_add_tail(&newmsg->user_info_list, &udp_online_head);
  137. J_UDP++;
  138. //3.显示客户登入信息
  139. printf("[%s]上线了!\n", msg->self_name);
  140. char addr[16];
  141. u_short port1,port2;
  142. inet_ntop(AF_INET, (void *)&(newmsg->cli_addr_udp.sin_addr.s_addr), addr, sizeof(addr));
  143. port1 = ntohs(newmsg->cli_addr_udp.sin_port);
  144. port2 = ntohs(newmsg->cli_addr_tcp.sin_port);
  145. printf("客户上线信息:%s:UDP[%d] TCP[%d]\n", addr, port1, port2);
  146. finded_name = NO_FIND;
  147. //4.重新广播
  148. int ret = -1;
  149. ret = send_online_info(); // 自己“已上线”信息
  150. do{
  151. sleep(3);
  152. ret = send_online_info(); // 自己“已上线”信息
  153. }while (ret == -1);
  154. }
  155. break;
  156. }
  157. case OFFLINE: //下线
  158. {
  159. struct list_head *n2 = NULL;
  160. list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
  161. {
  162. pos2 = list_entry(p2, struct user_info, user_info_list);
  163. if (strncmp(msg->self_name, pos2->user_name, strlen(pos2->user_name)) == 0)
  164. {
  165. printf("[%s]下线!\n", pos2->user_name);
  166. J_UDP--;
  167. list_del(&pos2->user_info_list); //删除用户
  168. free(pos2);
  169. }
  170. }
  171. break;
  172. }
  173. case CHAT_ONE: //私聊
  174. {
  175. struct servmsg_udp *newmsg;
  176. newmsg = (struct servmsg_udp *)malloc(sizeof(struct servmsg_udp));
  177. if(strncmp(msg->aim_name, MY_NAME, strlen(MY_NAME)) == 0) //接受的数据包,如果是发给自己的,就加入链表;否则丢弃
  178. {
  179. //1.添加尾部
  180. memcpy(&(newmsg->recvmsg), msg, sizeof(struct msg_udp)); //数据
  181. //2.加入链表
  182. list_add_tail(&newmsg->servmsg_udp_list, &udp_data_head);
  183. I_UDP++;
  184. }
  185. //修改聊天对象
  186. char *aim_name, *aim_name_of_other;
  187. struct sockaddr_in *addr_udp_find;
  188. aim_name = addr_return_name(&msg->self_addr_udp);
  189. aim_name_of_other = addr_return_name(&OTHER_UDP_ADDR);
  190. addr_udp_find = name_reurn_addr(1, aim_name);
  191. // pr_debug("上个对话:%s, 将要对话:%s\n",aim_name,aim_name_of_other);
  192. if(aim_name == NULL || addr_udp_find == NULL)
  193. ;
  194. else if (aim_name_of_other == NULL)
  195. {
  196. pr_debug("修改对象为:%s\n->",aim_name);
  197. udp_info_check(addr_udp_find);
  198. bzero(&OTHER_UDP_ADDR, sizeof(struct sockaddr_in));
  199. memcpy(&OTHER_UDP_ADDR, addr_udp_find, sizeof(struct sockaddr_in));
  200. aim_name = addr_return_name(&OTHER_UDP_ADDR);
  201. pr_debug("现在对象为:%s\n",aim_name);
  202. }
  203. else if(strncmp(aim_name, aim_name_of_other, strlen(aim_name_of_other)) != 0)
  204. {
  205. char reply;
  206. printf("是否改变聊天对象为:[%s]? ++y/++n", aim_name);
  207. while(CHANGE_AIM_IF_IN != 1)
  208. {
  209. printf("等待输入...\n");
  210. sleep(1);
  211. }
  212. reply = DATAIN[0];
  213. CHANGE_AIM_IF_IN = 0;
  214. if(reply == 'y')
  215. {
  216. bzero(&OTHER_UDP_ADDR, sizeof(struct sockaddr_in));
  217. memcpy(&OTHER_UDP_ADDR, addr_udp_find, sizeof(struct sockaddr_in));
  218. }
  219. else if (reply == 'n')
  220. {
  221. ;
  222. }
  223. }
  224. break;
  225. }
  226. case CHAT_ALL: //群发
  227. {
  228. struct servmsg_udp *newmsg;
  229. newmsg = (struct servmsg_udp *)malloc(sizeof(struct servmsg_udp));
  230. //1.添加尾部
  231. memcpy(&(newmsg->recvmsg), msg, sizeof(struct msg_udp)); //数据
  232. //2.加入链表
  233. list_add_tail(&newmsg->servmsg_udp_list, &udp_data_head);
  234. I_UDP++;
  235. break;
  236. }
  237. case REFRESH: //列表 登入类型中 已加入
  238. {
  239. /*
  240. pr_debug("[%s]请求列表!\n", msg->self_name);
  241. struct servmsg_udp *newmsg;
  242. newmsg = (struct servmsg_udp *)malloc(sizeof(struct servmsg_udp));
  243. //1.添加尾部
  244. memcpy(&(newmsg->recvmsg), &msg, sizeof(msg)); //数据
  245. //2.修改类型,通过私聊发送
  246. newmsg->recvmsg.type_udp = CHAT_ONE;
  247. //3.添加内容data
  248. strcpy(newmsg->recvmsg.data, "用户列表:");
  249. struct list_head *n2 = NULL;
  250. list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
  251. {
  252. pos2 = list_entry(p2, struct user_info, user_info_list);
  253. sprintf(newmsg->recvmsg.data, "[%s] [%s]", newmsg->recvmsg.data, pos2->user_name);
  254. }
  255. sprintf(newmsg->recvmsg.data, "%s%c", newmsg->recvmsg.data, '\n');
  256. pr_debug("用户列表:%s\n", newmsg->recvmsg.data);
  257. //4.加入链表
  258. list_add_tail(&newmsg->list, &udp_data_head);
  259. I_UDP++;
  260. */
  261. break;
  262. }
  263. case UPLOAD: //上传
  264. {
  265. struct servmsg_udp *newmsg;
  266. newmsg = (struct servmsg_udp *)malloc(sizeof(struct servmsg_udp));
  267. /*1.填写IP与端口*/
  268. memcpy(&(newmsg->recvmsg.self_name), msg->self_name, sizeof(msg->self_name)); //客户名
  269. memcpy(&(newmsg->recvmsg.aim_addr_udp), &msg->aim_addr_udp, sizeof(msg->aim_addr_udp)); //IP地址与端口号
  270. /*3.填写数据*/
  271. char *cut_p;
  272. cut_p = strtok(msg->data, "_");
  273. cut_p = strtok(NULL, "_");
  274. sprintf(newmsg->recvmsg.data, "%s:%s\n", msg->self_name, cut_p);
  275. newmsg->recvmsg.data[UDP_MAXSIZE] = 0;
  276. newmsg->recvmsg.data_size = strlen(newmsg->recvmsg.data);
  277. pr_debug("UDP接收加入链表【%s】\n", cut_p);
  278. /*3.填加到链表*/
  279. list_add_tail(&newmsg->servmsg_udp_list, &udp_data_head);
  280. I_UDP++;
  281. break;
  282. }
  283. case DOWNLOAD: //下载
  284. {
  285. // 待续
  286. /*1.下载列表*/
  287. if (strncmp(msg->data, "list", 4) == 0)
  288. {
  289. //查找list
  290. struct list_head *n1 = NULL;
  291. list_for_each_safe(p1, n1, &udp_data_head) //安全遍历聊天
  292. {
  293. pos1 = list_entry(p1, struct servmsg_udp, servmsg_udp_list);
  294. if (pos1->recvmsg.type_udp == UPLOAD)
  295. {
  296. udp_send_to(inet_ntoa(msg->aim_addr_udp.sin_addr),msg->aim_addr_udp.sin_port, \
  297. &pos1->recvmsg, sizeof(pos1->recvmsg));
  298. }
  299. }
  300. }
  301. char read_file(struct sockaddr_in *cin, char *way);
  302. /*2.遍历查找UPLOAD,修改接受者(不用删除下载链表)*/
  303. if (strncmp(msg->data, "start", 5) == 0)
  304. {
  305. char *cut_p;
  306. struct sockaddr_in aim_tcp_addr;//他人信息
  307. cut_p = strtok(msg->data, ":");
  308. cut_p = strtok(NULL, ":");
  309. /********************根据UDP修改客户地址********************/
  310. aim_tcp_addr.sin_family = AF_INET;
  311. aim_tcp_addr.sin_port = msg->aim_addr_udp.sin_port;
  312. aim_tcp_addr.sin_addr.s_addr = msg->aim_addr_udp.sin_addr.s_addr;
  313. bzero(aim_tcp_addr.sin_zero, 8);
  314. /***********************************************************/
  315. if (access(cut_p, F_OK) != 0)
  316. {
  317. read_file(&aim_tcp_addr, cut_p);
  318. }
  319. else
  320. printf("文件不存在!\n");
  321. }
  322. break;
  323. }
  324. default:
  325. break;
  326. }
  327. return 0;
  328. }
  329. void *udp_linked_list_manage(void *arg)
  330. {
  331. sleep(2);
  332. pr_debug("UDP链表管理\n");
  333. static int num_i=0, num_j=0;
  334. while (1)
  335. {
  336. if (num_j != J_UDP)
  337. pr_debug("** 上线:%d **\n", J_UDP);
  338. /********************************************************************
  339. if (num_i != I_UDP || num_j != J_UDP)
  340. pr_debug("** 聊天:%d,上线:%d **\n", I_UDP, J_UDP);
  341. *********************************************************************/
  342. num_i = I_UDP;
  343. num_j = J_UDP;
  344. //1.通过对小结构体的遍历,来获得大结构体的数据
  345. struct list_head *n1 = NULL;
  346. list_for_each_safe(p1, n1, &udp_data_head) //安全遍历聊天
  347. {
  348. pos1 = list_entry(p1, struct servmsg_udp, servmsg_udp_list);
  349. //2.根据类型,处理数据
  350. // printf("类型:%d,data=%s\n", pos1->recvmsg.type_udp, pos1->recvmsg.data);
  351. switch (pos1->recvmsg.type_udp)
  352. {
  353. case LOG_IN: //登入
  354. {
  355. //登入信息不需要处理,直接用--list命令可查看的登入者信息
  356. break;
  357. }
  358. case OFFLINE: //下线
  359. {
  360. //有用户下线,则直接删除登入者的链表信息
  361. break;
  362. }
  363. case REFRESH: //列表
  364. {
  365. //在接收线程,修改类型,通过私聊发送出
  366. break;
  367. }
  368. case UPLOAD: //上传
  369. {
  370. //在接收线程处理了
  371. break;
  372. }
  373. case DOWNLOAD: //下载
  374. {
  375. //在接收线程处理了
  376. break;
  377. }
  378. case CHAT_ONE: //私聊
  379. {
  380. /*提取聊天包,打印*/
  381. if(strncmp(pos1->recvmsg.aim_name, MY_NAME, strlen(MY_NAME)) == 0)
  382. {
  383. char addr[16];
  384. u_short port;
  385. inet_ntop(AF_INET, (void *)&(pos1->recvmsg.self_addr_udp.sin_addr.s_addr), addr, sizeof(addr));
  386. port = ntohs(pos1->recvmsg.self_addr_udp.sin_port);
  387. pr_debug("发送者:%s,接收者:%s\n", pos1->recvmsg.self_name, pos1->recvmsg.aim_name);
  388. pr_debug("发送客户地址:%s:%d\n", addr, port);
  389. pr_debug("内容[%d字节]:%s \n", pos1->recvmsg.data_size, pos1->recvmsg.data);
  390. if (strncmp(pos1->recvmsg.data, "quit", 4) == 0)
  391. {
  392. pr_debug("[%s]结束与[%s]的聊天!\n", pos1->recvmsg.self_name, pos1->recvmsg.aim_name);
  393. }
  394. I_UDP--;
  395. list_del(&pos1->servmsg_udp_list); //处理完后删除聊天
  396. free(pos1);
  397. }
  398. break;
  399. }
  400. case CHAT_ALL: //群聊
  401. {
  402. /*提取聊天包,发送给目标*/
  403. struct list_head *n2 = NULL;
  404. list_for_each_safe(p2, n2, &udp_online_head) //重新遍历上线
  405. {
  406. pos2 = list_entry(p2, struct user_info, user_info_list);
  407. if (strncmp(pos1->recvmsg.aim_name, pos2->user_name, strlen(pos2->user_name)) == 0)
  408. {//在用户列表中,找到了
  409. continue;
  410. }
  411. pr_debug("发送者:%s,接收者:%s\n", pos1->recvmsg.self_name, pos1->recvmsg.aim_name);
  412. char addr[16];
  413. u_short port;
  414. inet_ntop(AF_INET, (void *)&(pos2->cli_addr_udp.sin_addr.s_addr), addr, sizeof(addr));
  415. port = ntohs(pos2->cli_addr_udp.sin_port);
  416. pr_debug("发送客户地址:%s:%d\n", addr, port);
  417. /*截取聊天信息*/
  418. pos1->recvmsg.data[UDP_MAXSIZE] = 0;
  419. printf("内容[%d字节]:%s \n", pos1->recvmsg.data_size, pos1->recvmsg.data);
  420. if (strncmp(pos1->recvmsg.data, "quit", 4) == 0)
  421. {
  422. pr_debug("[%s]结束群聊!\n", pos1->recvmsg.self_name);
  423. }
  424. else
  425. {
  426. port = ntohs(pos2->cli_addr_udp.sin_port);
  427. udp_send_to(inet_ntoa(pos2->cli_addr_udp.sin_addr),port, \
  428. &pos1->recvmsg, sizeof(pos1->recvmsg));
  429. }
  430. }
  431. I_UDP--;
  432. list_del(&pos1->servmsg_udp_list); //处理完后删除聊天
  433. free(pos1);
  434. break;
  435. }
  436. default:
  437. break;
  438. }
  439. }
  440. }
  441. return NULL;
  442. }
  443. /*UDP接收数据*/
  444. void *recv_udp(void *arg)
  445. {
  446. sleep(1);
  447. pr_debug("UDP接收数据\n");
  448. struct sockaddr_in cin; //发送者信息
  449. char ret;
  450. /*3.接收数据包*/
  451. struct msg_udp msg; //收到他人发来的包
  452. while (1)
  453. {
  454. ret = udp_recv_from(SELF_IP, SELF_PORT_UDP, &cin, &msg);
  455. if (ret < 0) //真正出错了
  456. {
  457. perror("recvfrom");
  458. continue;
  459. }
  460. else
  461. {
  462. //加入链表
  463. udp_linked_list_add(&msg);
  464. }
  465. }
  466. return NULL;
  467. }
  468. /*UDP广播接收数据*/
  469. void *recv_broad_udp(void *arg)
  470. {
  471. sleep(1);
  472. pr_debug("UDP广播接收数据\n");
  473. struct sockaddr_in cin; //发送者信息
  474. char ret;
  475. /*3.接收数据包*/
  476. struct msg_udp msg; //收到他人发来的包
  477. while (1)
  478. {
  479. ret = udp_broad_recv_from(BROADCAST_RECV_IP, BROADCAST_RECV_PORT_UDP, &cin, &msg);
  480. if (ret < 0) //真正出错了
  481. {
  482. perror("recvfrom");
  483. continue;
  484. }
  485. else
  486. {
  487. //加入链表
  488. pr_debug("UDP广播接收数据类型:%d\n", msg.type_udp);
  489. udp_linked_list_add(&msg);
  490. }
  491. }
  492. return NULL;
  493. }
  494. /******************************************以上UDP部分******************************************************/
  495. /******************************************各功能模块*******************************************************/
  496. /*私聊*/
  497. void talk(char *name, char *str)
  498. {
  499. if(!name && !str)
  500. pr_debug("私聊\n");
  501. int ret;
  502. static char aim_name[20];
  503. /*获取对方名字*/
  504. struct msg_udp msg_data;
  505. if(!name)
  506. {
  507. pthread_mutex_lock(&lock1);
  508. printf("对方名字:");
  509. ret = scanf("%s", aim_name); //对方名字
  510. pthread_mutex_unlock(&lock1);
  511. //加入临时聊天对象
  512. aim_name[19] = '\0';
  513. bzero(&OTHER_UDP_ADDR, sizeof(struct sockaddr_in));
  514. struct sockaddr_in *return_udp_addr = name_reurn_addr(1, aim_name);
  515. if(return_udp_addr)
  516. memcpy(&OTHER_UDP_ADDR, return_udp_addr, sizeof(struct sockaddr_in));
  517. }
  518. else
  519. strcpy(aim_name, name);
  520. printf("现对话为:%s\n", aim_name);
  521. /*2.发送数据包*/
  522. char buf[UDP_MAXSIZE+1];
  523. bzero(buf, UDP_MAXSIZE+1);
  524. if(!str)
  525. {
  526. pthread_mutex_lock(&lock1);
  527. printf("请输入内容:\n");
  528. ret = scanf("%s", buf);
  529. pthread_mutex_unlock(&lock1);
  530. // char *s;
  531. // fflush(stdin);
  532. // s = fgets(buf, UDP_MAXSIZE, stdin);
  533. //printf("用户[%s]输入:\n", MY_NAME);
  534. }
  535. else{
  536. strcpy(buf, str);}
  537. buf[UDP_MAXSIZE] = 0;
  538. if (strlen(aim_name) > 0 && strlen(buf) > 0)
  539. {
  540. struct sockaddr_in *aim_udp_addr;
  541. aim_udp_addr = name_reurn_addr(1, aim_name);
  542. if (aim_udp_addr) //找到此用户,则发送;否则加入链表
  543. {
  544. //填写数据包信息
  545. msg_data.type_udp = CHAT_ONE; //聊天类型
  546. strcpy(msg_data.self_name, MY_NAME); //自己名字
  547. strcpy(msg_data.aim_name, aim_name); //目标名字
  548. msg_data.data_size = strlen(buf); //数据大小
  549. buf[msg_data.data_size-1] = 0;
  550. memcpy(msg_data.data, buf, msg_data.data_size); //数据
  551. memcpy(&msg_data.self_addr_udp, &SELF_UDP_ADDR, sizeof(SELF_UDP_ADDR)); //自己地址
  552. memcpy(&msg_data.aim_addr_udp, &pos2->cli_addr_udp, sizeof(pos2->cli_addr_udp));//目标地址
  553. udp_addr_send_to(aim_udp_addr, &msg_data, sizeof(msg_data));
  554. }
  555. }
  556. if (strncmp(buf, "quit", 4) == 0)
  557. {
  558. msg_data.type_udp = NO_HANDLE; //不处理类型
  559. play();
  560. }
  561. }
  562. /*群聊*/
  563. void toall(void)
  564. {
  565. pr_debug("群聊\n");
  566. char *s;
  567. struct msg_udp msg_data;
  568. /*2.发送数据包*/
  569. char buf[UDP_MAXSIZE+1];
  570. bzero(buf, UDP_MAXSIZE+1);
  571. fflush(stdin);
  572. s = fgets(buf, UDP_MAXSIZE, stdin);
  573. //printf("用户[%s]输入:\n", MY_NAME);
  574. buf[UDP_MAXSIZE] = 0;
  575. if (strlen(buf) >= 0)
  576. {
  577. struct list_head *n2 = NULL;
  578. list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
  579. {
  580. pos2 = list_entry(p2, struct user_info, user_info_list);
  581. char ip[16];
  582. u_short port;
  583. inet_ntop(AF_INET, (void *)&(pos2->cli_addr_udp.sin_addr.s_addr), ip, sizeof(ip));
  584. port = ntohs(pos2->cli_addr_udp.sin_port);
  585. //填写数据包信息
  586. msg_data.type_udp = CHAT_ALL; //聊天类型
  587. strcpy(msg_data.self_name, MY_NAME); //自己名字
  588. strcpy(msg_data.aim_name, pos2->user_name); //目标名字
  589. msg_data.data_size = strlen(buf); //数据大小
  590. buf[msg_data.data_size-1] = 0;
  591. memcpy(msg_data.data, buf, msg_data.data_size); //数据
  592. memcpy(&msg_data.self_addr_udp, &SELF_UDP_ADDR, sizeof(SELF_UDP_ADDR)); //自己地址
  593. memcpy(&msg_data.aim_addr_udp, &pos2->cli_addr_udp, sizeof(pos2->cli_addr_udp));//目标地址
  594. udp_send_to(ip, port, &msg_data, sizeof(msg_data));
  595. }
  596. }
  597. if (strncmp(buf, "quit", 4) == 0)
  598. {
  599. msg_data.type_udp = NO_HANDLE; //不处理类型
  600. play();
  601. }
  602. }
  603. /*下线*/
  604. void lgout(void)
  605. {
  606. int ret =-1;
  607. /*填写数据包信息*/
  608. struct msg_udp msg_data;
  609. msg_data.type_udp = OFFLINE; //退出类型
  610. strcpy(msg_data.self_name, MY_NAME); //自己名字
  611. /*发送*/
  612. ret = udp_broad_send_to(BROADCAST_SEND_IP, BROADCAST_SEND_PORT_UDP, &msg_data, sizeof(msg_data)); //广播
  613. IF_DOWN = 0;
  614. if (ret != -1)
  615. {
  616. printf("下线成功!\n");
  617. }
  618. }
  619. /*列表*/
  620. void list(void)
  621. {
  622. pr_debug("列表\n");
  623. struct servmsg_udp newmsg;
  624. struct list_head *n2 = NULL;
  625. bzero(&newmsg.recvmsg.data, UDP_MAXSIZE+1);
  626. list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
  627. {
  628. pos2 = list_entry(p2, struct user_info, user_info_list);
  629. if(strlen((char *)&newmsg.recvmsg.data) == 0)
  630. {
  631. sprintf(newmsg.recvmsg.data, "%s", pos2->user_name);
  632. }
  633. else
  634. {
  635. sprintf(newmsg.recvmsg.data, "%s %s", newmsg.recvmsg.data, pos2->user_name);
  636. }
  637. }
  638. sprintf(newmsg.recvmsg.data, "%s%c", newmsg.recvmsg.data, '\n');
  639. printf("用户列表:%s\n", newmsg.recvmsg.data);
  640. }
  641. /*=====================================以下TCP部分=====================================*/
  642. void *tcp_linked_list_manage(void *arg)
  643. {
  644. sleep(2);
  645. pr_debug("TCP链表管理\n");
  646. int file_wrfd;
  647. static int num_i=0, num_j=0;
  648. static int sequence_i = 0; //数据顺序
  649. size_t alto=0;
  650. while (1)
  651. {
  652. if(num_j != J_TCP)
  653. printf("** 下载:%d **\n", J_TCP);
  654. num_i = I_TCP;
  655. num_j = J_TCP;
  656. //1.通过对小结构体的遍历,来获得大结构体的数据
  657. struct list_head *n3 = NULL;
  658. list_for_each_safe(p3, n3, &tcp_data_head) //安全遍历聊天
  659. {
  660. pos3 = list_entry(p3, struct servmsg_tcp, servmsg_tcp_list);
  661. char pr_data1[20];
  662. memcpy(pr_data1, pos3->recvmsg.data,19);
  663. printf("link->type:%d,data:%s\n",pos3->recvmsg.type_tcp, pr_data1);
  664. //2.根据类型,处理数据
  665. // printf("类型:%d,data=%s\n", pos1->recvmsg.type_udp, pos1->recvmsg.data);
  666. switch (pos3->recvmsg.type_tcp)
  667. {
  668. case DOWN_IF: //是否下载
  669. {
  670. printf("用户[%s]发来文件[%s],是否接收?(==y,==n)\n", addr_return_name(&pos3->recvmsg.self_addr_tcp), pos3->recvmsg.data);
  671. char reply;
  672. while(DOWN_IF_IN != 1)
  673. {
  674. printf("等待输入...\n");
  675. sleep(1);
  676. }
  677. reply = DATAIN[0];
  678. DOWN_IF_IN = 0;
  679. if (reply == 'y')
  680. {
  681. printf("同意接受文件[%s]\n", pos3->recvmsg.data);
  682. //填写资料
  683. struct msg_tcp msg;
  684. char *aim_name = addr_return_name(&pos3->recvmsg.self_addr_tcp);
  685. if(aim_name)
  686. {
  687. msg.type_tcp = DOWN_YES; //类型
  688. /* | | */
  689. /* 让对方,进入下个选项 */
  690. strcpy(msg.self_name, MY_NAME); //自己的名字
  691. strcpy(msg.aim_name, aim_name); //目标名字
  692. msg.data_size = strlen("*no*"); //数据大小0 ~ 65535
  693. strcpy(msg.data, "*no*"); //数据
  694. msg.data[TCP_MAXSIZE] = 0;
  695. memcpy(&msg.self_addr_tcp, &SELF_TCP_ADDR, sizeof(struct sockaddr_in)); //自己tcp地址
  696. memcpy(&msg.aim_addr_tcp, &pos3->recvmsg.self_addr_tcp, sizeof(struct sockaddr_in)); //目标地址
  697. if(tcp_addr_send_to(&pos3->recvmsg.self_addr_tcp, &msg, sizeof(msg)))//发送TCP上传信息,文件名
  698. {
  699. printf("DOWN_YES发送成功!\n");
  700. }
  701. else
  702. {
  703. printf("DOWN_YES发送失败!\n");
  704. break;
  705. }
  706. }
  707. else
  708. printf("确认下载,填写资料有错\n");
  709. I_TCP--;
  710. list_del(&pos3->servmsg_tcp_list); //处理完后删除询问
  711. free(pos3);
  712. }
  713. break;
  714. }
  715. /*====================================================*
  716. 1.对方收到DOWN_YES, 发送DOWN_START, [等待...]
  717. 2.自己收到DOWN_START, 建立文件, 发送DOWN_READY
  718. 3.对方收到DOWN_READY, 发送DOWN_LOADING, [继续...]
  719. 4.直到发送完
  720. *====================================================*/
  721. case DOWN_YES: //对方收到确认,上传过来
  722. {
  723. //读取文件,并发送
  724. printf("收到确认,准备发送!\n");
  725. struct sockaddr_in *cin = &pos3->recvmsg.self_addr_tcp;
  726. char *way = UP_WAY;
  727. struct msg_tcp msg;
  728. char *aim_name = addr_return_name(cin);
  729. if(aim_name)
  730. {
  731. msg.type_tcp = DOWN_START; //类型
  732. strcpy(msg.self_name, MY_NAME); //自己的名字
  733. strcpy(msg.aim_name, aim_name); //目标名字
  734. memcpy(&msg.self_addr_tcp, &SELF_TCP_ADDR, sizeof(struct sockaddr_in)); //自己tcp地址
  735. memcpy(&msg.aim_addr_tcp, cin, sizeof(struct sockaddr_in)); //目标地址
  736. char *cut_p = NULL, *cut_q = NULL;
  737. char copy_way[UDP_MAXSIZE+1];
  738. strcpy(copy_way, way);
  739. copy_way[UDP_MAXSIZE] = 0;
  740. cut_p = strtok(copy_way, "/");
  741. while(cut_p){
  742. cut_q = cut_p;
  743. cut_p = strtok(NULL, "/");
  744. if(!cut_p)
  745. break;
  746. }
  747. msg.data_size = strlen(cut_q); //数据大小0 ~ 65535
  748. bzero(msg.data, TCP_MAXSIZE+1);
  749. strcpy(msg.data, cut_q); //数据
  750. msg.data[TCP_MAXSIZE] = 0;
  751. printf("%s,%s\n", cut_q,way);
  752. tcp_info_check(cin);
  753. if(tcp_addr_send_to(cin, &msg, sizeof(msg)))
  754. {
  755. printf("DOWN_START发送成功!\n");
  756. }
  757. else
  758. {
  759. printf("DOWN_START发送失败!\n");
  760. break;
  761. }
  762. }
  763. else
  764. {
  765. printf("read_file->aim_name 错误!\n");
  766. break;
  767. }
  768. I_TCP--;
  769. list_del(&pos3->servmsg_tcp_list); //处理完后删除确认
  770. free(pos3);
  771. break;
  772. }
  773. case DOWN_NO: //拒绝下载
  774. {
  775. break;
  776. }
  777. case DOWN_START: //下载开始
  778. {
  779. /************************开始创建文件*****************************************************************************************/
  780. char *file_name = pos3->recvmsg.data;
  781. printf("[%s]下载开始!\n", file_name);
  782. file_wrfd = open(file_name, O_RDWR | O_CREAT | O_APPEND, 0666);
  783. struct down_info *newinfo;
  784. newinfo = (struct down_info *)malloc(sizeof(struct down_info));
  785. //1.添加信息
  786. strcpy(newinfo->user_name, pos3->recvmsg.self_name); //用户名字
  787. newinfo->file_wrfd = file_wrfd; //文件fd
  788. memcpy(&newinfo->cli_addr_tcp, &pos3->recvmsg.self_addr_tcp, sizeof(struct sockaddr_in)); //客户端tcp地址
  789. //2.加入链表
  790. list_add_tail(&newinfo->down_info_list, &tcp_accept_head);
  791. J_TCP++;
  792. //3.收到DOWN_START,发送准备好了
  793. struct msg_tcp msg;
  794. char *aim_name = addr_return_name(&pos3->recvmsg.self_addr_tcp);
  795. if(aim_name)
  796. {
  797. msg.type_tcp = DOWN_READY; //类型
  798. /* | | */
  799. /* 让对方,进入下个选项 */
  800. strcpy(msg.self_name, MY_NAME); //自己的名字
  801. strcpy(msg.aim_name, aim_name); //目标名字
  802. msg.data_size = strlen("*no*"); //数据大小0 ~ 65535
  803. strcpy(msg.data, "*no*"); //数据
  804. msg.data[TCP_MAXSIZE] = 0;
  805. memcpy(&msg.self_addr_tcp, &SELF_TCP_ADDR, sizeof(struct sockaddr_in)); //自己tcp地址
  806. memcpy(&msg.aim_addr_tcp, &pos3->recvmsg.self_addr_tcp, sizeof(struct sockaddr_in)); //目标地址
  807. if(tcp_addr_send_to(&pos3->recvmsg.self_addr_tcp, &msg, sizeof(msg)))//发送TCP上传信息,文件名
  808. {
  809. printf("DOWN_READY发送成功!\n");
  810. }
  811. else
  812. {
  813. printf("DOWN_READY发送失败!\n");
  814. break;
  815. }
  816. }
  817. else
  818. printf("确认下载,填写资料有错\n");
  819. sequence_i = 0;
  820. I_TCP--;
  821. list_del(&pos3->servmsg_tcp_list); //处理完后删除开始下载
  822. free(pos3);
  823. break;
  824. }
  825. case DOWN_READY: //继续DOWN_YES的read_file上传
  826. {
  827. printf("收到DOWN_READY\n");
  828. DOWN_READY_IF = 1;
  829. read_file(&pos3->recvmsg.self_addr_tcp, UP_WAY);
  830. I_TCP--;
  831. list_del(&pos3->servmsg_tcp_list); //处理完后删除开始下载
  832. free(pos3);
  833. break;
  834. }
  835. case DOWN_LOADING: //正在下载
  836. {
  837. printf("正在下载!\n");
  838. char pr_data[20];
  839. memcpy(pr_data, pos3->recvmsg.data,19);
  840. pr_debug("数据[%s]\n", pr_data);
  841. printf("接受顺序:%d, 自定顺序:%d\n", pos3->recvmsg.data_sequence, sequence_i);
  842. struct list_head *n4 = NULL;
  843. list_for_each_safe(p4, n4, &tcp_accept_head) //安全遍历聊天
  844. {
  845. pos4 = list_entry(p4, struct down_info, down_info_list);
  846. printf("user_name:%s,self_name:%s\n", pos4->user_name, pos3->recvmsg.self_name);
  847. if (strncmp(pos4->user_name, pos3->recvmsg.self_name, strlen(pos3->recvmsg.self_name)) == 0)
  848. {
  849. printf("数据顺序:%d, 数据大小:%d\n", pos3->recvmsg.data_sequence, pos3->recvmsg.data_size);
  850. int ret;
  851. if(pos3->recvmsg.data_sequence == sequence_i)
  852. {
  853. ret = write(pos4->file_wrfd, &pos3->recvmsg.data, pos3->recvmsg.data_size);
  854. sequence_i++;
  855. alto += pos3->recvmsg.data_size;
  856. I_TCP--;
  857. list_del(&pos3->servmsg_tcp_list); //处理完后删除正在下载
  858. free(pos3);
  859. }
  860. }
  861. }
  862. break;
  863. }
  864. case DOWN_END: //下载结束
  865. {
  866. printf("对方发送[%s]完成!\n", pos3->recvmsg.data);
  867. printf("接收大小[%.2fk], 实际大小[%.2fk]\n", alto*1.0/1024, pos3->recvmsg.alto_size*1.0/1024);
  868. struct list_head *n4 = NULL;
  869. list_for_each_safe(p4, n4, &tcp_accept_head) //安全遍历聊天
  870. {
  871. pos4 = list_entry(p4, struct down_info, down_info_list);
  872. if (strncmp(pos4->user_name, pos3->recvmsg.self_name, strlen(pos3->recvmsg.self_name)) == 0)
  873. {
  874. if(pos3->recvmsg.data_sequence == sequence_i)
  875. {
  876. printf("关闭文件[%d]\n", pos4->file_wrfd);
  877. close(pos4->file_wrfd);
  878. sequence_i = 0;
  879. alto = 0;
  880. I_TCP--;
  881. free(pos3);
  882. list_del(&pos3->servmsg_tcp_list); //处理完后删除下载结束
  883. J_TCP--;
  884. list_del(&pos4->down_info_list); //删除用户
  885. free(pos4);
  886. }
  887. }
  888. }
  889. break;
  890. }
  891. case UP_YES: //确认上传
  892. {
  893. /*
  894. struct sockaddr_in cin;
  895. char buf[TCP_MAXSIZE+1];
  896. tcp_addr_recv_from(&SELF_TCP_ADDR, &cin, buf);
  897. buf[TCP_MAXSIZE] = 0;
  898. char *name=addr_return_name(&cin);
  899. if(strncmp(buf, "ifdown|yes", strlen("ifdown|yes")))//ifdown|yes
  900. printf("对方[%s],同意接收,请输入2,再回车", name);
  901. else
  902. printf("对方[%s],拒绝接收,返回请 --quit,继续请重新选择", name);
  903. */
  904. break;
  905. }
  906. case UP_NO: //拒绝上传
  907. {
  908. break;
  909. }
  910. default:
  911. break;
  912. }
  913. }
  914. }
  915. return NULL;
  916. }
  917. /*TCP接收数据*/
  918. void *recv_tcp(void *arg)
  919. {
  920. sleep(1);
  921. pr_debug("TCP接收数据\n");
  922. /*5.接收数据包*/
  923. int ret = -1 ;
  924. struct sockaddr_in cin; //发送者信息
  925. struct msg_tcp msg; //收到他人发来的包
  926. int tcp_addr_fd = tcp_addr_ini(&SELF_TCP_ADDR);
  927. while (1)
  928. {
  929. bzero(&msg, sizeof(msg));
  930. if(tcp_addr_fd)
  931. {
  932. ret = tcp_addr_recv_from(tcp_addr_fd, &cin, &msg);
  933. printf("while体中recv\n");
  934. tcp_info_check(&cin);
  935. if (ret < 0) //真正出错了
  936. {
  937. perror("tcp_addr_recv_from");
  938. continue;
  939. }
  940. else if(ret >0)
  941. {
  942. printf("recv->type:%d\n",msg.type_tcp);
  943. struct servmsg_tcp *newmsg;
  944. newmsg = (struct servmsg_tcp *)malloc(sizeof(struct servmsg_tcp));
  945. //1.添加尾部
  946. memcpy(&(newmsg->recvmsg), &msg, sizeof(msg)); //数据
  947. //2.加入链表
  948. list_add_tail(&newmsg->servmsg_tcp_list, &tcp_data_head);
  949. I_TCP++;
  950. }
  951. }
  952. }
  953. return NULL;
  954. }
  955. /*上传文件*/
  956. char read_file(struct sockaddr_in *cin, char *way)
  957. {
  958. int file_rdfd;
  959. char buf[TCP_MAXSIZE+1];
  960. int sequence_i = 0;
  961. struct msg_tcp msg;
  962. size_t size, alto, real_num=0;
  963. while(!DOWN_READY_IF)
  964. {
  965. sleep(1);
  966. printf("等待DOWN_READY回复\n");
  967. }
  968. DOWN_READY_IF = 0;
  969. file_rdfd = open(way, O_RDONLY, 0644);
  970. alto = size = lseek(file_rdfd, 0L, SEEK_END) - lseek(file_rdfd, 0L, SEEK_SET);
  971. if (alto == 0)
  972. {
  973. pr_debug("空文件!\n");
  974. }
  975. while (size >= TCP_MAXSIZE) //文件大于5k,则每8k上传
  976. {
  977. bzero(buf, TCP_MAXSIZE+1);
  978. lseek(file_rdfd, 0L, real_num);
  979. if (read(file_rdfd, buf, TCP_MAXSIZE) > 0)
  980. {
  981. msg.type_tcp = DOWN_LOADING; //类型
  982. strcpy(msg.self_name, MY_NAME); //自己的名字
  983. char *aim_name = addr_return_name(cin);
  984. if(aim_name)
  985. strcpy(msg.aim_name, aim_name); //目标名字
  986. msg.data_size = TCP_MAXSIZE; //数据大小0 ~ 65535
  987. msg.data_sequence = sequence_i;
  988. bzero(msg.data, TCP_MAXSIZE+1);
  989. memcpy(msg.data, buf, TCP_MAXSIZE); //数据
  990. msg.data[TCP_MAXSIZE] = 0;
  991. if (tcp_addr_send_to(cin, &msg, sizeof(msg)))
  992. {
  993. sequence_i++;
  994. real_num += TCP_MAXSIZE;
  995. size -= TCP_MAXSIZE;
  996. printf("上传 >5k %.2f%%\n", real_num*100.0/alto);
  997. }
  998. }
  999. else
  1000. {
  1001. printf("读取文件失败1\n");
  1002. }
  1003. }
  1004. while (size < TCP_MAXSIZE && size > 0) //小于5k,则按size大小上传
  1005. {
  1006. bzero(buf, TCP_MAXSIZE+1);
  1007. lseek(file_rdfd, 0L, real_num);
  1008. if (read(file_rdfd, buf, size) != -1)
  1009. {
  1010. msg.type_tcp = DOWN_LOADING; //类型
  1011. strcpy(msg.self_name, MY_NAME); //自己的名字
  1012. char *aim_name = addr_return_name(cin);
  1013. if(aim_name)
  1014. strcpy(msg.aim_name, aim_name); //目标名字
  1015. msg.data_size = size; //数据大小0 ~ 65535
  1016. msg.data_sequence = sequence_i;
  1017. bzero(msg.data, TCP_MAXSIZE+1);
  1018. memcpy(msg.data, buf, size); //数据
  1019. msg.data[TCP_MAXSIZE] = 0;
  1020. if (tcp_addr_send_to(cin, &msg, sizeof(msg)))
  1021. {
  1022. sequence_i++;
  1023. real_num = real_num + size;
  1024. size = size - size;
  1025. printf("上传 <5k %.2f%%\n", real_num*100.0/alto);
  1026. break;
  1027. }
  1028. }
  1029. else
  1030. {
  1031. printf("读取文件失败2\n");
  1032. }
  1033. }
  1034. msg.type_tcp = DOWN_END; //类型
  1035. strcpy(msg.self_name, MY_NAME); //自己的名字
  1036. char *aim_name = addr_return_name(cin);
  1037. if(aim_name)
  1038. strcpy(msg.aim_name, aim_name); //目标名字
  1039. msg.data_size = strlen("upend"); //数据大小0 ~ 65535
  1040. msg.data_sequence = sequence_i;
  1041. msg.alto_size = alto;
  1042. bzero(msg.data, TCP_MAXSIZE+1);
  1043. strcpy(msg.data, "upend"); //数据
  1044. msg.data[TCP_MAXSIZE] = 0;
  1045. if (tcp_addr_send_to(cin, &msg, sizeof(msg))) //上传完成
  1046. {
  1047. printf("上传完成!\n发送大小[%.2fk], 实际大小[%.2fk]\n", alto*1.0/1024, real_num*1.0/1024);
  1048. }
  1049. else
  1050. printf("上传失败!\n");
  1051. close(file_rdfd);
  1052. return 0;
  1053. }
  1054. /*上传*/
  1055. void up(void)
  1056. {
  1057. int ret = -1;
  1058. ret = system("clear");
  1059. printf("this is UPLOAD\n");
  1060. printf("=============上传帮助=============\n");
  1061. printf("== 1.默认本目录+【文件名】 ==\n");
  1062. printf("== 2.【完整文件路径】 ==\n");
  1063. printf("== 3.查看上传文件列表 ==\n");
  1064. printf("== 4.退出 ==\n");
  1065. printf("==================================\n");
  1066. up_ord();
  1067. }
  1068. void up_ord(void)
  1069. {
  1070. int ret = -1;
  1071. char *s;
  1072. char ord[10];
  1073. pthread_mutex_lock(&lock1);
  1074. printf("选择命令:");
  1075. ret = scanf("%s", ord);
  1076. pthread_mutex_unlock(&lock1);
  1077. if (strncmp(ord, "clear", 5) == 0)
  1078. {
  1079. up();
  1080. }
  1081. else if (!((strlen(ord) == 1) && (ord[0] == '1' || '2' || '3' || '4')))
  1082. {
  1083. printf("输入选项错误,进入命令界面!\n");
  1084. play();
  1085. }
  1086. else
  1087. {
  1088. switch (atoi(ord))
  1089. {
  1090. char file_name[20];
  1091. char aim_name[20];
  1092. static struct sockaddr_in *aim_addr_udp = NULL;
  1093. case 1:
  1094. {
  1095. pr_debug("进入选项1\n");
  1096. s = getcwd(UP_WAY, sizeof(UP_WAY));
  1097. pthread_mutex_lock(&lock1);
  1098. printf("当前目录下,请输入文件名:\n");
  1099. ret = scanf("%s", file_name);
  1100. pthread_mutex_unlock(&lock1);
  1101. sprintf(UP_WAY,"%s/%s", UP_WAY, file_name);
  1102. if (access(UP_WAY, F_OK | R_OK) == 0)
  1103. {
  1104. pr_debug("[%s]存在!\n", file_name);
  1105. pthread_mutex_lock(&lock1);
  1106. printf("接收者名字:\n");
  1107. ret = scanf("%s", aim_name);
  1108. pthread_mutex_unlock(&lock1);
  1109. struct sockaddr_in *aim_addr_tcp = name_reurn_addr(2, aim_name);
  1110. //填写资料
  1111. struct msg_tcp msg;
  1112. if(aim_addr_tcp)
  1113. {
  1114. msg.type_tcp = DOWN_IF; //类型
  1115. strcpy(msg.self_name, MY_NAME); //自己的名字
  1116. strcpy(msg.aim_name, aim_name); //目标名字
  1117. msg.data_size = strlen(file_name); //数据大小0 ~ 65535
  1118. strcpy(msg.data, file_name); //数据
  1119. msg.data[TCP_MAXSIZE] = 0;
  1120. memcpy(&msg.self_addr_tcp, &SELF_TCP_ADDR, sizeof(struct sockaddr_in)); //自己tcp地址
  1121. memcpy(&msg.aim_addr_tcp, aim_addr_tcp, sizeof(struct sockaddr_in)); //目标地址
  1122. tcp_addr_send_to(aim_addr_tcp, &msg, sizeof(msg));//发送TCP上传信息,文件名
  1123. printf("上传请求成功!\n");
  1124. }
  1125. else
  1126. printf("上传,填写资料有错\n");
  1127. }
  1128. break;
  1129. }
  1130. case 2:
  1131. {
  1132. pr_debug("进入选项2\n");
  1133. s = fgets(UP_WAY, sizeof(UP_WAY), stdin);
  1134. if (access(UP_WAY, F_OK | R_OK) == 0)
  1135. {
  1136. char *cut_p;
  1137. cut_p = strtok(UP_WAY, "/");
  1138. while (cut_p)
  1139. {
  1140. cut_p = strtok(NULL, "/");
  1141. }
  1142. pr_debug("[%s]存在!\n", cut_p);
  1143. char file_info[30];
  1144. sprintf(file_info, "if_down%s", cut_p);
  1145. tcp_send_to(OTHER_IP, OTHER_PORT_TCP, file_info, sizeof(file_info));//发送TCP上传信息,文件名
  1146. /*填写数据包信息*/
  1147. struct msg_udp msg_data;
  1148. msg_data.type_udp = UPLOAD; //聊天类型
  1149. strcpy(msg_data.self_name, MY_NAME); //自己名字
  1150. sprintf(msg_data.data, "upstart_%s", cut_p); //发送UDP上传信息,文件名
  1151. udp_send_to(OTHER_IP, OTHER_PORT_TCP, &msg_data, sizeof(msg_data));//发送UDP上传信息,文件名
  1152. if(aim_addr_udp)
  1153. read_file(aim_addr_udp, UP_WAY);
  1154. }
  1155. break;
  1156. }
  1157. case 3:
  1158. {
  1159. pr_debug("进入选项3\n");
  1160. //发送下载列表信息
  1161. break;
  1162. }
  1163. case 4:
  1164. {
  1165. pr_debug("进入选项4\n");
  1166. play();
  1167. break;
  1168. }
  1169. }
  1170. }
  1171. }
  1172. /*下载*/
  1173. void down(void)
  1174. {
  1175. int ret = -1;
  1176. char *s;
  1177. ret = system("clear");
  1178. printf("this is DOWNLOAD\n");
  1179. printf("==============下载帮助==============\n");
  1180. printf("== 1.默认本目录,为下载路径 ==\n");
  1181. printf("== 2.输入下载文件路径 ==\n");
  1182. printf("== 3.查看下载文件列表 ==\n");
  1183. printf("== 4.开始下载 ==\n");
  1184. printf("== 5.退出 ==\n");
  1185. printf("====================================\n");
  1186. char ord[10];
  1187. pthread_mutex_lock(&lock1);
  1188. printf("命令:");
  1189. ret = scanf("%s", ord);
  1190. pthread_mutex_unlock(&lock1);
  1191. if (!((strlen(ord) == 1) && (ord[0] == '1' || '2' || '3' || '4')))
  1192. {
  1193. printf("输入选项错误,进入命令界面!\n");
  1194. play();
  1195. }
  1196. switch (atoi(ord))
  1197. {
  1198. case 1:
  1199. {
  1200. pr_debug("进入选项1\n");
  1201. s = getcwd(DOWN_WAY, sizeof(DOWN_WAY));
  1202. break;
  1203. }
  1204. case 2:
  1205. {
  1206. pr_debug("进入选项2\n");
  1207. s = fgets(DOWN_WAY, sizeof(DOWN_WAY), stdin);
  1208. if (access(DOWN_WAY, F_OK | R_OK) == 0)
  1209. {
  1210. pr_debug("目录存在,可以下载!\n");
  1211. }
  1212. else
  1213. {
  1214. char ord[50] = "mkdir -p ";
  1215. sprintf(ord, "%s%s", ord, DOWN_WAY);
  1216. ret = system(DOWN_WAY);
  1217. pr_debug("目录不存在,创建成功,可以下载!\n");
  1218. }
  1219. break;
  1220. }
  1221. case 3:
  1222. {
  1223. pr_debug("进入选项3\n");
  1224. //发送下载列表信息
  1225. /*TCP地址信息*/
  1226. struct msg_udp usron;
  1227. usron.type_udp = DOWNLOAD; //上线类型
  1228. strcpy(usron.self_name, MY_NAME); //自己名字
  1229. strcpy(usron.data, "list"); //list标识
  1230. usron.aim_addr_udp.sin_family = AF_INET; //他人地址
  1231. usron.aim_addr_udp.sin_port = htons(OTHER_PORT_UDP); //UDP接收列表
  1232. usron.aim_addr_udp.sin_addr.s_addr = inet_addr(OTHER_IP);
  1233. bzero(usron.aim_addr_udp.sin_zero, 8);
  1234. udp_send_to(OTHER_IP, OTHER_PORT_TCP, &usron, sizeof(usron));//发送UDP上传信息,文件名
  1235. break;
  1236. }
  1237. case 4:
  1238. {
  1239. pr_debug("进入选项4\n");
  1240. //发送下载列表信息
  1241. /*TCP地址信息*/
  1242. struct msg_udp usron;
  1243. usron.type_udp = DOWNLOAD; //上线类型
  1244. strcpy(usron.self_name, MY_NAME); //自己名字
  1245. char file_name[30];
  1246. printf("请输入文件名:");
  1247. ret = scanf("%s", file_name);
  1248. sprintf(usron.data, "start:%s", file_name);//start标识
  1249. usron.aim_addr_udp.sin_family = AF_INET; //他人地址
  1250. usron.aim_addr_udp.sin_port = htons(OTHER_PORT_TCP); //TCP接收文件
  1251. usron.aim_addr_udp.sin_addr.s_addr = inet_addr(OTHER_IP);
  1252. bzero(usron.aim_addr_udp.sin_zero, 8);
  1253. udp_send_to(OTHER_IP, OTHER_PORT_TCP, &usron, sizeof(usron));//发送UDP上传信息,文件名
  1254. break;
  1255. }
  1256. case 5:
  1257. {
  1258. pr_debug("进入选项4\n");
  1259. play();
  1260. break;
  1261. }
  1262. }
  1263. }
  1264. struct sockaddr_in *name_reurn_addr(int type, char *aim_name)
  1265. {
  1266. int finded_name = NO_FIND;
  1267. struct list_head *n2 = NULL;
  1268. list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
  1269. {
  1270. pos2 = list_entry(p2, struct user_info, user_info_list);
  1271. if (strncmp(aim_name, pos2->user_name, strlen(pos2->user_name)) == 0)
  1272. {
  1273. finded_name = HAVE_FIND;
  1274. if(type == 1)
  1275. return &pos2->cli_addr_udp;
  1276. else if(type == 2)
  1277. return &pos2->cli_addr_tcp;
  1278. else
  1279. return NULL;
  1280. }
  1281. }
  1282. if (finded_name != HAVE_FIND) //找到此用户,则发送;否则加入链表
  1283. {
  1284. printf("未找到[%s]此用户\n", aim_name);
  1285. return NULL;
  1286. }
  1287. return NULL;
  1288. }
  1289. char *addr_return_name(struct sockaddr_in *addr)
  1290. {
  1291. int finded_name = NO_FIND;
  1292. struct list_head *n2 = NULL;
  1293. list_for_each_safe(p2, n2, &udp_online_head) //安全遍历上线
  1294. {
  1295. pos2 = list_entry(p2, struct user_info, user_info_list);
  1296. if (memcmp(&pos2->cli_addr_tcp.sin_addr, &addr->sin_addr, sizeof(struct in_addr)) == 0)
  1297. {
  1298. finded_name = HAVE_FIND;
  1299. return pos2->user_name;
  1300. }
  1301. }
  1302. if (finded_name != HAVE_FIND) //找到此用户,则发送;否则加入链表
  1303. {
  1304. char ip[16];
  1305. u_short port;
  1306. inet_ntop(AF_INET, (void *)&(addr->sin_addr.s_addr), ip, sizeof(ip));
  1307. port = ntohs(addr->sin_port);
  1308. printf("未找到[%s:%d]此用户\n", ip, port);
  1309. return NULL;
  1310. }
  1311. return NULL;
  1312. }
  1313. /*=====================================以上TCP部分=====================================*/
  1314. /*帮助*/
  1315. void help(void)
  1316. {
  1317. pr_debug("帮助\n");
  1318. int ret =-1;
  1319. ret = system("clear");
  1320. printf("this is Help\n");
  1321. printf("=================帮助=================\n");
  1322. printf("== 1.命令格式:“--” + “命令” ==\n");
  1323. printf("== 2.聊天时,使用quit退出聊天 ==\n");
  1324. printf("== 3.使用clear回到,命令界面 ==\n");
  1325. printf("== 4.如果ctrl+c,则下线,程序结束 ==\n");
  1326. printf("== 5.输入quit,退出帮助界面 ==\n");
  1327. printf("======================================\n");
  1328. }
  1329. /*判断(命令)*/
  1330. void judge(char *ord)
  1331. {
  1332. if(!ord);
  1333. else if (strncmp(ord, "help", 4) == 0)
  1334. {
  1335. help();
  1336. }
  1337. else if (strncmp(ord, "clear", 5) == 0)
  1338. {
  1339. play();
  1340. }
  1341. else if (strncmp(ord, "talk", 4) == 0)
  1342. {
  1343. talk(NULL, NULL);
  1344. }
  1345. else if (strncmp(ord, "down", 4) == 0)
  1346. {
  1347. down();
  1348. }
  1349. else if (strncmp(ord, "list", 4) == 0)
  1350. {
  1351. list();
  1352. }
  1353. else if (strncmp(ord, "lgout", 5) == 0)
  1354. {
  1355. lgout();
  1356. }
  1357. else if (strncmp(ord, "toall", 5) == 0)
  1358. {
  1359. toall();
  1360. }
  1361. else if (strncmp(ord, "up", 2) == 0)
  1362. {
  1363. up();
  1364. }
  1365. else
  1366. {
  1367. printf("没有这个命令!\n");
  1368. }
  1369. }
  1370. /*显示*/
  1371. void play(void)
  1372. {
  1373. int ret = -1;
  1374. ret = system("clear");
  1375. printf("this is LAN chat\n");
  1376. printf("=================命令===============\n");
  1377. printf("== --help 帮助 --lgout 下线 ==\n");
  1378. printf("== --talk 私聊 --toall 群聊 ==\n");
  1379. printf("== --down 下载 --up 上传 ==\n");
  1380. printf("== --list 列表 --clear 清屏 ==\n");
  1381. printf("====================================\n");
  1382. }
  1383. /*命令 或 聊天*/
  1384. void order_or_chat(char *ord)
  1385. {
  1386. char ret;
  1387. char *cut_p;
  1388. char *aim_name;
  1389. char new_ord[UDP_MAXSIZE+1];
  1390. while(IF_ORD_IN == 0);
  1391. if (!ord) //为空,输入
  1392. {
  1393. bzero(new_ord, UDP_MAXSIZE+1);
  1394. pthread_mutex_lock(&lock1);
  1395. printf("请输入命令或消息:\n");
  1396. ret = scanf("%s", new_ord);
  1397. pthread_mutex_unlock(&lock1);
  1398. order_or_chat(new_ord);
  1399. }
  1400. else if (strncmp(ord, "--", 2) == 0) //不为空,直接去掉--
  1401. {
  1402. cut_p = strtok(ord, "--");
  1403. if (cut_p)
  1404. {
  1405. judge(cut_p);
  1406. }
  1407. }
  1408. else if (strncmp(ord, "++", 2) == 0) //不为空,直接去掉--
  1409. {
  1410. cut_p = strtok(ord, "++");
  1411. if (cut_p && cut_p[0] == 'y')
  1412. {
  1413. printf("cut_p:%s\n", cut_p);
  1414. strcpy(DATAIN, cut_p);
  1415. CHANGE_AIM_IF_IN = 1;
  1416. }
  1417. }
  1418. else if (strncmp(ord, "==", 2) == 0) //不为空,直接去掉--
  1419. {
  1420. cut_p = strtok(ord, "==");
  1421. if (cut_p && cut_p[0] == 'y')
  1422. {
  1423. printf("cut_p:%s\n", cut_p);
  1424. strcpy(DATAIN, cut_p);
  1425. DOWN_IF_IN = 1;
  1426. }
  1427. }
  1428. else
  1429. {
  1430. aim_name = addr_return_name(&OTHER_UDP_ADDR);
  1431. if(aim_name && ord) //找到用户
  1432. {
  1433. talk(aim_name, ord);
  1434. }
  1435. else
  1436. {
  1437. send_online_info();
  1438. }
  1439. }
  1440. order_or_chat(NULL);
  1441. }
  1442. void nametrue(int argc, char *argv[])
  1443. {
  1444. if (argc >= 2)
  1445. {
  1446. memcpy(MY_NAME, argv[1], strlen(argv[1])); //自己名字
  1447. }
  1448. else
  1449. {
  1450. strcpy(MY_NAME, "xx");
  1451. printf("please input your name!\n");
  1452. }
  1453. }
  1454. void func(int signo)
  1455. {
  1456. lgout();
  1457. pr_debug("\n[%s]退出!\n", MY_NAME);
  1458. exit(1);
  1459. }
  1460. /*填写本机绑定IP、端口号*/
  1461. char info_udp_tcp(void)
  1462. {
  1463. SELF_UDP_ADDR.sin_family = AF_INET; //自己UDP地址
  1464. SELF_UDP_ADDR.sin_port = htons(SELF_PORT_UDP);
  1465. SELF_UDP_ADDR.sin_addr.s_addr = inet_addr(SELF_IP);
  1466. bzero(SELF_UDP_ADDR.sin_zero, 8);
  1467. SELF_TCP_ADDR.sin_family = AF_INET; //自己TCP地址
  1468. SELF_TCP_ADDR.sin_port = htons(SELF_PORT_TCP);
  1469. SELF_TCP_ADDR.sin_addr.s_addr = inet_addr(SELF_IP);
  1470. bzero(SELF_TCP_ADDR.sin_zero, 8);
  1471. return 0;
  1472. }
  1473. /*登入线程*/
  1474. void *loading_thread(void *arg)
  1475. {
  1476. play(); //显示界面
  1477. info_udp_tcp(); //tcp udp 信息IP端口绑定
  1478. loading_udp(); //上线
  1479. sleep(3);
  1480. order_or_chat(NULL); //命令判断->进入各功能
  1481. return NULL;
  1482. }
  1483. int main(int argc, char *argv[])
  1484. {
  1485. nametrue(argc, argv); //处理输入名字
  1486. pr_debug("昵称:%s\n", MY_NAME); //测试名字
  1487. signal(SIGINT, func); //注册Ctrl + C
  1488. pthread_mutex_init(&lock1, NULL); //初始化锁1
  1489. pthread_t tid1; //登入、命令处理
  1490. pthread_t tid2; //UDP接收线程,聊天
  1491. pthread_t tid3; //UDP广播接收线程,上线
  1492. pthread_t tid4; //TCP接收线程,文件传送
  1493. pthread_t tid5; //循环遍历,结构体处理,类型UDP
  1494. pthread_t tid6; //循环遍历,结构体处理,类型TCP
  1495. pthread_create(&tid1, NULL, loading_thread, NULL);
  1496. pthread_create(&tid2, NULL, recv_udp, NULL);
  1497. pthread_create(&tid3, NULL, recv_broad_udp, NULL);
  1498. pthread_create(&tid4, NULL, recv_tcp, NULL);
  1499. pthread_create(&tid5, NULL, udp_linked_list_manage, NULL);
  1500. pthread_create(&tid6, NULL, tcp_linked_list_manage, NULL);
  1501. pthread_join(tid1, NULL);
  1502. pthread_join(tid2, NULL);
  1503. pthread_join(tid3, NULL);
  1504. pthread_join(tid4, NULL);
  1505. pthread_join(tid5, NULL);
  1506. pthread_join(tid6, NULL);
  1507. return 0;
  1508. }