socket 파일 전송 기능 구현

41720 단어 소켓(소켓)
이 절 에서 우 리 는 socket 파일 전송 프로그램 을 완성 합 니 다. 이것 은 매우 실 용적 인 예 입 니 다.구현 할 기능 은 클 라 이언 트 가 server 에서 파일 을 다운로드 하여 로 컬 로 저장 하 는 것 입 니 다.
이 프로그램 을 작성 하려 면 두 가지 문 제 를 주의해 야 합 니 다.
1) 파일 크기 가 불확실 하여 버퍼 보다 훨씬 클 수 있 습 니 다. write () / send () 함 수 를 한 번 호출 하면 파일 내용 의 전송 을 완성 할 수 없습니다.데 이 터 를 받 을 때 도 같은 상황 이 발생 한다.
이 문 제 를 해결 하려 면 while 순환 을 사용 할 수 있 습 니 다. 예 를 들 어:
  1. //Server
  2. int nCount; while( (nCount = fread(buffer, 1, BUF_SIZE, fp)) > 0 ){ send(sock, buffer, nCount, 0); }
    //Client int nCount; while( (nCount = recv(clntSock, buffer, BUF_SIZE, 0)) > 0 ){ fwrite(buffer, nCount, 1, fp); } Server , ,fread() 0, 。

    Client , , recv() 0, while 。
    : recv() 0, , 。
    2) Client , —— while 。

    while recv() 0, , recv() 0 ?recv() 0 FIN 。

    FIN , FIN , read()/recv() , , 0, ”socket “。

    shutdown() FIN :server close()/closesocket() , , shutdown() 。

    Windows ,Linux , 。 。

    server.cpp:
     
         
    1. #include
    2. #include
    3. #include
    4. #pragma comment (lib, "ws2_32.lib") // ws2_32.dll
    5. #define BUF_SIZE 1024
    6. int main(){
    7. //
    8. char *filename = "D:\\send.avi"; //
    9. FILE *fp = fopen(filename, "rb"); //
    10. if(fp == NULL){
    11. printf("Cannot open file, press any key to exit!
      ");
    12. system("pause");
    13. exit(0);
    14. }
    15. WSADATA wsaData;
    16. WSAStartup( MAKEWORD(2, 2), &wsaData);
    17. SOCKET servSock = socket(AF_INET, SOCK_STREAM, 0);
    18. sockaddr_in sockAddr;
    19. memset(&sockAddr, 0, sizeof(sockAddr));
    20. sockAddr.sin_family = PF_INET;
    21. sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    22. sockAddr.sin_port = htons(1234);
    23. bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
    24. listen(servSock, 20);
    25. SOCKADDR clntAddr;
    26. int nSize = sizeof(SOCKADDR);
    27. SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
    28. // ,
    29. char buffer[BUF_SIZE] = {0}; //
    30. int nCount;
    31. while( (nCount = fread(buffer, 1, BUF_SIZE, fp)) > 0 ){
    32. send(clntSock, buffer, nCount, 0);
    33. }
    34. shutdown(clntSock, SD_SEND); // , , FIN
    35. recv(clntSock, buffer, BUF_SIZE, 0); // ,
    36. fclose(fp);
    37. closesocket(clntSock);
    38. closesocket(servSock);
    39. WSACleanup();
    40. system("pause");
    41. return 0;
    42. }

            
     
        
    1. #include
    2. #include
    3. #include
    4. #pragma comment(lib, "ws2_32.lib")
    5. #define BUF_SIZE 1024
    6. int main(){
    7. // ,
    8. char filename[100] = {0}; //
    9. printf("Input filename to save: ");
    10. gets(filename);
    11. FILE *fp = fopen(filename, "wb"); // ( )
    12. if(fp == NULL){
    13. printf("Cannot open file, press any key to exit!
      ");
    14. system("pause");
    15. exit(0);
    16. }
    17. WSADATA wsaData;
    18. WSAStartup(MAKEWORD(2, 2), &wsaData);
    19. SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    20. sockaddr_in sockAddr;
    21. memset(&sockAddr, 0, sizeof(sockAddr));
    22. sockAddr.sin_family = PF_INET;
    23. sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    24. sockAddr.sin_port = htons(1234);
    25. connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
    26. // ,
    27. char buffer[BUF_SIZE] = {0}; //
    28. int nCount;
    29. while( (nCount = recv(sock, buffer, BUF_SIZE, 0)) > 0 ){
    30. fwrite(buffer, nCount, 1, fp);
    31. }
    32. puts("File transfer success!");
    33. // , shutdown()
    34. fclose(fp);
    35. closesocket(sock);
    36. WSACleanup();
    37. system("pause");
    38. return 0;
    39. }
    D send.avi , server, client:
    Input filename to save: D:\\recv.avi↙
    //
    File transfer success!

    D recv.avi, send.avi , 。

    server.cpp 42 ,recv() client , client closesocket() ,server FIN ,recv() , 。

좋은 웹페이지 즐겨찾기