分享

windows下C++的socket编程入门--文件传输

 禁忌石 2018-03-03


原创 2014年01月09日 01:10:23

招着官方教程一步步做


主要函数或步骤:

  • WSAStartup, 初始化,WSACleanup,结束
  • socket(, ,) 构造函数,要有socket的instance才能实现传输
  • send() 
  • recv()
  • listen(), server端开始要监听自己的端口号有没有被连接
  • bind(),server的用来listen()的socket绑定address
  • accept(),如果没有client要连接,server在调用时就阻塞,有client要连接,就从这个要连接的队列里取出然后accept,然后server产生一个新的socket,而之前在listen()的socket是和这个不一样的,微软为何要弄两个socket出来呢,网上有一些解释,似乎是为了使用时更清楚一点


全部代码再后面可以直接找到

运行:先运行server的exe,再运行client的exe

这样就学会了基本的C/S传输

然后再加入文件操作:在server打开一个文件,从文件里读入内容,一个个包传过去,一直读到文件结束;在client创建一个用来接收传输内容的文件,一个个包接收过来,接收过来的内容写在这个文件里。

以下是我用官网代码修改后的文件传输系统

  1. /*server.cpp*/  
  2. #ifndef WIN32_LEAN_AND_MEAN  
  3. #define WIN32_LEAN_AND_MEAN  
  4. #endif  
  5.   
  6. #include <Windows.h>  
  7. #include <WinSock2.h>  
  8. #include <WS2tcpip.h>  
  9. #include <IPHlpApi.h>  
  10. #include <cstdio>  
  11.   
  12. #pragma comment (lib, "Ws2_32.lib")  
  13.   
  14. #define DEFAULT_PORT "27015"  
  15. #define DEFAULT_BUFLEN 512  
  16.   
  17.   
  18.   
  19. int main ()  
  20. {  
  21.     int iResult, iSendResult;  
  22.     WSADATA wsaData;  
  23.     struct addrinfo *result = NULL, *ptr = NULL, hints;  
  24.     char temp[DEFAULT_BUFLEN];  
  25.   
  26.     printf("input the file you want to transfer\n");  
  27.     scanf("%s", temp);  
  28.     //strcpy(temp, "input.txt");  
  29.   
  30.     // open file   
  31.     FILE * fp = fopen(temp, "rb"); // binary mode for read  
  32.     if(fp == NULL)  
  33.     {  
  34.         printf("open file %s failed\n", temp);  
  35.         return -1;  
  36.     }  
  37.   
  38.     if(WSAStartup(MAKEWORD(2, 2), &wsaData))  
  39.     {  
  40.         printf("server WSAStartup failed: %d\n", iResult);  
  41.         return 1;  
  42.     }  
  43.   
  44.     ZeroMemory(&hints, sizeof(hints));  
  45.     hints.ai_family = AF_INET;  
  46.     hints.ai_socktype = SOCK_STREAM;  
  47.     hints.ai_protocol = IPPROTO_TCP;  
  48.     hints.ai_flags = AI_PASSIVE; // caller to bind  
  49.   
  50.     // resolve the local address and port to be used by user  
  51.     iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);  
  52.     if(iResult != 0)  
  53.     {  
  54.         printf("server getaddrinfo faild: %d\n", iResult);  
  55.         WSACleanup();  
  56.         return 1;  
  57.     }  
  58.       
  59.     // create a socket for server  
  60.     SOCKET ListenSocket = INVALID_SOCKET;  
  61.     ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);  
  62.     if(ListenSocket == INVALID_SOCKET)  
  63.     {  
  64.         printf("server failed at socket(): %ld\n", WSAGetLastError());  
  65.         freeaddrinfo(result);  
  66.         WSACleanup();  
  67.         return 1;  
  68.     }  
  69.   
  70.     // bind a socket  
  71.     iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);  
  72.     if(iResult == SOCKET_ERROR)  
  73.     {  
  74.         printf("server bind faild: %ld\n", WSAGetLastError());  
  75.         freeaddrinfo(result);  
  76.         closesocket(ListenSocket);  
  77.         WSACleanup();  
  78.         return 1;  
  79.     }  
  80.     freeaddrinfo(result); // once bind, no longer needed  
  81.   
  82.     // listen on a socket  
  83.     if(listen(ListenSocket, SOMAXCONN))  
  84.     {  
  85.         printf("server listen socket failed %ld\n", WSAGetLastError());  
  86.         closesocket(ListenSocket);  
  87.         WSACleanup();  
  88.         return 1;  
  89.     }  
  90.   
  91.       
  92.     // accept a connection  
  93.     sockaddr_in client_addr;  
  94.     int nlen;  
  95.     SOCKET ClientSocket = INVALID_SOCKET;  
  96.     ClientSocket = accept(ListenSocket, NULL, NULL);  
  97.     if(ClientSocket == INVALID_SOCKET)  
  98.     {  
  99.         printf("server accept failed: %ld\n",WSAGetLastError());  
  100.         closesocket(ListenSocket);  
  101.         WSACleanup();  
  102.         return 1;  
  103.     }  
  104.     //char *ip = inet_ntoa(client_addr.sin_addr);  
  105.     //printf("establish connection to server %s\n", ip);  
  106.   
  107.     // no longer need  
  108.     closesocket(ListenSocket);  
  109.   
  110.     // file operation and send data  
  111.       
  112.     int num = 0;  
  113.     while(!feof(fp))  
  114.     {  
  115.         num = fread(temp, 1, DEFAULT_BUFLEN, fp);  
  116.         send(ClientSocket, temp, num, 0);  
  117.     }  
  118.     printf("server file transfer success\n");  
  119.       
  120.     fclose(fp);  
  121.     iResult = shutdown(ClientSocket, SD_SEND);  
  122.     if(iResult == SOCKET_ERROR)  
  123.     {  
  124.         printf("server shutdown failed %ld\n", WSAGetLastError());  
  125.         closesocket(ClientSocket);  
  126.         WSACleanup();  
  127.         return 1;  
  128.     }  
  129.     closesocket(ClientSocket);  
  130.     WSACleanup();  
  131.   
  132.     return 0;  
  133. }  

  1. /*client.cpp*/  
  2.   
  3. //prevent winsock.h (version 1.1)from being included by windows.h  
  4. #ifndef WIN32_LEAN_AND_MEAN  
  5. #define WIN32_LEAN_AND_MEAN  
  6. #endif  
  7. #include <Windows.h>  
  8. #include <winsock2.h>  
  9. #include <ws2tcpip.h>  
  10. #include <iphlpapi.h> // after winsock2.h  
  11. #include <cstdio>  
  12.   
  13. #pragma comment (lib, "Ws2_32.lib")  
  14. #pragma comment (lib, "Mswsock.lib")  
  15. #pragma comment (lib, "AdvApi32.lib")  
  16.   
  17. #define DEFAULT_PORT "27015"  
  18. #define DEFAULT_BUFLEN 512  
  19.   
  20.   
  21.   
  22.   
  23. int main ()  
  24. {  
  25.     int iResult;  
  26.     WSADATA wsaData;  
  27.     struct addrinfo *result = NULL, *ptr = NULL, hints;  
  28.     char sendbuf[] = "this is a test for client";  
  29.     char recvbuf[DEFAULT_BUFLEN];  
  30.     int recvbuflen = DEFAULT_BUFLEN;  
  31.     char temp[DEFAULT_BUFLEN], file_name[DEFAULT_BUFLEN];  
  32.   
  33.     printf("input ip address of server and file name\n");  
  34.     scanf("%s%s", temp, file_name);  
  35.   
  36.     //create file  
  37.     FILE *fp = fopen(file_name, "wb");  
  38.     if(fp == NULL)  
  39.     {  
  40.         printf("create file %s failed\n", file_name);  
  41.         return -1;  
  42.     }  
  43.   
  44.     // initialize  
  45.     if(WSAStartup(MAKEWORD(2,2), &wsaData))  
  46.     {  
  47.         printf("client WSAStartup failed: %d\n", iResult);  
  48.         return 1;  
  49.     }  
  50.   
  51.     ZeroMemory(&hints, sizeof(hints));  
  52.     hints.ai_family = AF_UNSPEC;  
  53.     hints.ai_socktype = SOCK_STREAM;  
  54.     hints.ai_protocol = IPPROTO_TCP;  
  55.   
  56.     // resolve the server address and port, argv[1] is server name  
  57.     iResult = getaddrinfo(temp, DEFAULT_PORT, &hints, &result);  
  58.     if(iResult != 0)  
  59.     {  
  60.         printf("client get addrinfor fail: %d\n", iResult);  
  61.         WSACleanup(); // terminate use of WS2_32.dll  
  62.         return 1;  
  63.     }  
  64.   
  65.       
  66.     SOCKET ConnectSocket = INVALID_SOCKET;  
  67.     for(ptr = result; ptr != NULL; ptr = ptr->ai_next)  
  68.     {  
  69.         // create a socket for client  
  70.         ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);  
  71.         if(ConnectSocket == INVALID_SOCKET)  
  72.         {  
  73.             printf("client socket failed with error %ld\n", WSAGetLastError());  
  74.             WSACleanup();  
  75.             return 1;  
  76.         }  
  77.   
  78.         // connect to server  
  79.         iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);  
  80.         if(iResult == SOCKET_ERROR)  
  81.         {  
  82.             closesocket(ConnectSocket);  
  83.             ConnectSocket = INVALID_SOCKET;// if fail try next address returned by getaddrinfo  
  84.             continue;  
  85.         }  
  86.         break;  
  87.     }  
  88.   
  89.       
  90.     freeaddrinfo(result);  
  91.     if(ConnectSocket == INVALID_SOCKET)  
  92.     {  
  93.         printf("client unable to connect to server\n");  
  94.         WSACleanup();  
  95.         return 1;  
  96.     }  
  97.       
  98.     //receive data from server  
  99.     int num = 0;  
  100.     while (1)  
  101.     {  
  102.         num = recv(ConnectSocket, temp, DEFAULT_BUFLEN, 0);  
  103.         if(num == 0)   
  104.             break;  
  105.         fwrite(temp, 1, num, fp);  
  106.     }  
  107.     printf("transmission done\n");  
  108.   
  109.     fclose(fp);  
  110.     closesocket(ConnectSocket);  
  111.     WSACleanup();  
  112.   
  113.     return 0;  
  114. }  


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多