1. 程式人生 > >基於UDT connect連接通信以及文件傳輸--客戶端

基於UDT connect連接通信以及文件傳輸--客戶端

文章 pan detail break fin 文件名 plain mes oca

上面一篇文章中提出了服務端的,其實這裏沒有嚴格意義的服務端和客戶端之分,因為我在代碼中是基於UDP的,不存在服務端與客戶端,兩個都是對等的,只是我這裏進行一下簡單的區分而已。在這裏,客戶端所進行的主要操作就是首先給服務端發送文件名,然後將文件直接通過fopen(),fread()等一系列的操作將文件發送過去。

與客戶端相對應的源碼在另一篇博文中:http://blog.csdn.net/pingd/article/details/16341467

CLIENT端

[cpp] view plain copy
  1. #include <iostream>
  2. #include "udt.h"
  3. #include <io.h>
  4. #pragma comment(lib,"ws2_32.lib")
  5. using namespace std;
  6. #define MAXLEN 4096
  7. int main(int argc,char *argv[])
  8. {
  9. if ((argc != 5))
  10. {
  11. cout<<"Usage: appclient.exe client_port server_ip server_port local_filename"<<endl;
  12. return 0;
  13. }
  14. //startup
  15. if (UDT::ERROR == UDT::startup())
  16. {
  17. cout<<"startup: "<<UDT::getlasterror().getErrorMessage()<<endl;
  18. }else{
  19. cout<<"startup suc..."<<endl;
  20. }
  21. //Initialize the UDT library
  22. UDTSOCKET client = UDT::socket(AF_INET, SOCK_DGRAM, 0);
  23. if (UDT::ERROR == client)
  24. {
  25. cout<<"socket: "<<UDT::getlasterror().getErrorMessage()<<endl;
  26. }else{
  27. cout<<"client suc..."<<endl;
  28. }
  29. //聲明udp socket
  30. int clientsocket = socket(AF_INET,SOCK_DGRAM,0);
  31. if (SOCKET_ERROR == clientsocket)
  32. {
  33. cout<<"udp socket error!"<<endl;
  34. }else{
  35. cout<<"clientsocket suc..."<<endl;
  36. }
  37. sockaddr_in serv_addr,my_addr;
  38. serv_addr.sin_family = AF_INET;
  39. serv_addr.sin_port = htons(atoi(argv[3]));
  40. serv_addr.sin_addr.s_addr = inet_addr(argv[2]);
  41. memset(&(serv_addr.sin_zero), ‘\0‘, 8);
  42. my_addr.sin_family = AF_INET;
  43. my_addr.sin_port = htons(atoi(argv[1]));
  44. my_addr.sin_addr.s_addr = INADDR_ANY;
  45. memset(&(my_addr.sin_zero), ‘\0‘, 8);
  46. bind(clientsocket,(struct sockaddr*)&my_addr,sizeof(my_addr));
  47. int mss = 1052;//最大傳輸單位
  48. //設置收發緩沖區大小 接收限時 和地址重用
  49. if( !( UDT::ERROR != (UDT::setsockopt(client, 0, UDT_SNDBUF, new int(32000), sizeof(int)))
  50. && UDT::ERROR != (UDT::setsockopt(client, 0, UDP_RCVBUF, new int(32000), sizeof(int)))
  51. && UDT::ERROR != (UDT::setsockopt(client,0,UDT_REUSEADDR,new int(1),sizeof(int)))
  52. && UDT::ERROR != (UDT::setsockopt(client, 0, UDT_RENDEZVOUS, new bool(true), sizeof(bool))))
  53. && UDT::ERROR != (UDT::setsockopt(client, 0, UDT_MSS, &mss, sizeof(int))))
  54. {
  55. cout<<"udt socket: "<<UDT::getlasterror().getErrorMessage()<<endl;
  56. UDT::close(client);
  57. return 0;
  58. }
  59. if (UDT::ERROR == UDT::bind2(client,clientsocket))
  60. {
  61. cout<<"udt bind2:"<<UDT::getlasterror().getErrorMessage()<<endl;
  62. return 0;
  63. }else{
  64. cout<<"bind2 suc"<<endl;
  65. }
  66. // connect to the server, implict bind
  67. if (UDT::ERROR == UDT::connect(client, (sockaddr*)&serv_addr, sizeof(serv_addr)))
  68. {
  69. cout << "connect: " << UDT::getlasterror().getErrorMessage();
  70. UDT::close(client);
  71. return 0;
  72. }else{
  73. cout<<"connect suc"<<endl;
  74. }
  75. char* hello = argv[4];
  76. if (UDT::ERROR == UDT::sendmsg(client, hello, strlen(hello) + 1,-1,true))
  77. {
  78. cout << "send: " << UDT::getlasterror().getErrorMessage();
  79. return 0;
  80. }
  81. FILE *fp;
  82. fp = fopen(hello,"rb");
  83. fseek(fp,0,SEEK_END);
  84. int filesize = ftell(fp);
  85. //rewind(fp);//移動到頭部
  86. fseek(fp,0,SEEK_SET);
  87. static int filepos = 0;//記錄文件偏移量
  88. cout<<"filesize = "<<filesize<<endl;
  89. char data[MAXLEN+1];
  90. int len=0,package=0;
  91. UDT::TRACEINFO trace;
  92. UDT::perfmon(client,&trace);
  93. while(1)
  94. {
  95. memset(data,0,sizeof(data));
  96. fread(data,MAXLEN,1,fp);
  97. if(filesize>=MAXLEN)
  98. {
  99. len = UDT::sendmsg(client,data,MAXLEN,-1,true);
  100. if (len<0)
  101. {
  102. cout<<"send failure!!\n"<<endl;
  103. break;
  104. }
  105. filesize -= MAXLEN;
  106. package ++;//record send all the packages
  107. }else
  108. {
  109. len = UDT::sendmsg(client,data,filesize,-1,true);
  110. if (len<0)
  111. {
  112. cout<<"send failure!!\n"<<endl;
  113. break;
  114. }
  115. package ++;//record recv all the packages
  116. char *quit = "quit";
  117. if (UDT::ERROR == UDT::sendmsg(client,quit,strlen(quit)+1,-1,true))
  118. {
  119. cout<<"send quit error"<<endl;
  120. fclose(fp);
  121. break;
  122. }
  123. break;
  124. }
  125. }
  126. UDT::perfmon(client,&trace);
  127. cout << "speed = " << trace.mbpsSendRate << "Mbits/sec" << endl;
  128. cout<<"send all the packages: "<<package<<endl;
  129. fclose(fp);
  130. UDT::close(client);
  131. UDT::close(clientsocket);
  132. UDT::cleanup();
  133. return 1;
  134. }

運行效果圖: 技術分享 註:要想運行這兩個程序直接把源代碼復制下來,然後去運行肯定是不行的,這個是需要UDT其它類庫的支持的,也就是說,需要你將UDT的源代碼文件拷貝進你的項目文件中才行。源代碼下載地址:http://blog.csdn.net/pingd/article/details/14519881 簡單截圖如下: 技術分享

基於UDT connect連接通信以及文件傳輸--客戶端