2013-03-02 2 views
-1

파일을 보낼 수있는 간단한 서버 및 클라이언트 그리고이 원본이 완료되었는지 확인해야합니다. 사촌 나는 그것이 전체 파일을 다운로드하지 않을 것 같아요.C++ Winsock 파일을 보내고

어쩌면이 소스에는 제한이 있습니까? 내가 업로드 사촌/200K 다운로드하고 조금 더 ..

서버 :

#include <WinSock2.h> 
#include <Windows.h> 
#include <stdio.h> 

#pragma comment(lib, "Ws2_32.lib") 

SOCKET Socket, Sub; 
WSADATA Winsock; 
sockaddr_in Addr; 
int Addrlen = sizeof(sockaddr_in); 
char Buffer[256]; 
char *Str; 
sockaddr_in IncomingAddress; 
int AddressLen = sizeof(IncomingAddress); 

int main() 
{ 
    WSAStartup(MAKEWORD(2, 2), &Winsock); // Start Winsock 

    if(LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) // Check version 
    { 
     WSACleanup(); 
     return 0; 
    } 

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

    ZeroMemory(&Addr, sizeof(Addr)); 
    Addr.sin_family = AF_INET; 
    Addr.sin_port = htons(6091); 
    bind(Socket, (sockaddr*)&Addr, sizeof(Addr)); 

    if(listen(Socket, 1) == SOCKET_ERROR) 
    { 
     printf("listening error\n"); 
    } 
    else 
    { 
     printf("listening ok\n"); 
    } 

    if(Sub = accept(Socket, (sockaddr*)&IncomingAddress, &AddressLen)) 
    { 
     char *ClientIP = inet_ntoa(IncomingAddress.sin_addr); 
     int ClientPort = ntohs(IncomingAddress.sin_port); 
     printf("Client conncted!\n"); 
     printf("IP: %s:%d\n", ClientIP, ClientPort); 

     printf("Sending file .. \n"); 


     FILE *File; 
     char *Buffer; 
     unsigned long Size; 

     File = fopen("C:\\Prog.exe", "rb"); 
     if(!File) 
     { 
      printf("Error while readaing the file\n"); 
      goto End; 
     } 

     fseek(File, 0, SEEK_END); 
     Size = ftell(File); 
     fseek(File, 0, SEEK_SET); 

     Buffer = new char[Size]; 

     fread(Buffer, Size, 1, File); 
     char cSize[MAX_PATH]; 
     sprintf(cSize, "%i", Size); 

     fclose(File); 

     send(Sub, cSize, MAX_PATH, 0); // File size 
     send(Sub, Buffer, Size, 0); // File Binary 
     free(Buffer); 

End: 
     closesocket(Sub); 
     closesocket(Socket); 
     WSACleanup(); 
    } 

    getchar(); 
    return 0; 
} 

클라이언트 :

#include <WinSock2.h> 
#include <Windows.h> 
#include <stdio.h> 

#pragma comment(lib, "Ws2_32.lib") 

SOCKET Socket; 
WSADATA Winsock; 
sockaddr_in Addr; 
int Addrlen = sizeof(Addr); 

int main() 
{ 
    WSAStartup(MAKEWORD(2, 2), &Winsock); // Start Winsock 

    if(LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) // Check version 
    { 
     WSACleanup(); 
     return 0; 
    } 

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

    ZeroMemory(&Addr, sizeof(Addr)); // clear the struct 
    Addr.sin_family = AF_INET; // set the address family 
    Addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    Addr.sin_port = htons(6091); // set the port 

    if(connect(Socket, (sockaddr*)&Addr, sizeof(Addr)) < 0) 
    { 
     printf("Connection failed !\n"); 
     getchar(); 
     return 0; 
    } 

    printf("Connection successful !\n"); 

    printf("Receiving file .. \n"); 

    int Size; 
    char *Filesize = new char[1024]; 

    if(recv(Socket, Filesize, 1024, 0)) // File size 
    { 
     Size = atoi((const char*)Filesize); 
     printf("File size: %d\n", Size); 
    } 

    char *Buffer = new char[Size]; 

    if(recv(Socket, Buffer, Size, 0)) // File Binary 
    { 
     FILE *File; 
     File = fopen("Prog.exe", "wb"); 
     fwrite((const char*)Buffer, 1, Size, File); 
     fclose(File); 
    } 

    getchar(); 
    closesocket(Socket); 
    WSACleanup(); 
    return 0; 
} 

감사합니다.

+0

파일을 쓰기 전에 클라이언트에서 버퍼의 내용을 확인해 보았습니까? –

+0

그게 무슨 소리 야? p.s 나는 사용하지 않은 몇 가지를 삭제했습니다. –

+0

문제 나 질문이 정확히 무엇인지는 분명하지 않습니다. – jogojapan

답변

4

많은 양의 데이터를 보내거나 받으려고하면 코드가 실패 할 수 있습니다. send function의 문서에서 :

반환 값 오류가 발생하지 않으면
, 반환에게 의 숫자가 보내도록 요청보다 적은 수 있습니다 전송 총 바이트 수, 를 보내 len 매개 변수. 그렇지 않으면 SOCKET_ERROR 값이 반송되고 특정 오류 코드는 WSAGetLastError을 호출하여 검색 할 수 있습니다.

당신은 send()의 반환 값을 확인해야하고, 그것을 전송 요청 바이트 수보다 작은 경우, 남아있는 데이터를 다시 send()를 호출합니다. 예 :

char *data = Buffer; // data to be sent 
int len = Size;  // number of bytes to be sent 
while (len > 0) { 
    int amount = send(Sub, data, len, 0); 
    if (amount == SOCKET_ERRROR) { 
     // handle error ... 
    } else { 
     len -= amount; 
     data += amount; 
    } 
} 

클라이언트에서 recv() 호출에 대해서도 마찬가지입니다.

+0

나는 그 주제에 빠져있다 :/당신은 저를 소스에 추가 할 수 있습니까 ..? 나는 노력했다. 그러나 그것은 나를 위해 일하지 않을 것이다; D –

0

이것은 파일을 바이너리로 읽고 파일을 전송하는 파일 전송 기능입니다. 이것은 독립적 인 함수로 v가 보내야하는 파일 경로와 함께 데이터를 보내야하는 소켓 값을 전달합니다.

void FileSend(SOCKET FileSendSocket,char *FilePath) 
{ 
    streampos filesize = 0; 
    ifstream in(FilePath,ios::binary); 
    ZeroMemory(&sendbuf, sendbuflen); 

    if(in.is_open()) 
    { 
     while(1) 
     { 
      in.read(sendbuf,sendbuflen); 
      if(in.eof()) 
      { 
       cout << "End of File sending from Client" << endl; 
       in.close(); 
       break; 
      } 
      else 
      { 
       send(FileSendSocket,sendbuf,sendbuflen,0); 
       ZeroMemory(&sendbuf, sendbuflen); 
      } 
     } 
    } 

} 

그리고 이것은 클라이언트 측에서 수신 기능이며, 그것은 바로 옆 수신 기능이 기능은 지속적으로 서버가 보내는 지금 어떤 데이터를 기록 할 호출해야합니다.

ofstream out("C:\\Prog.exe",ios::binary); 
void FileReceive(char* recvbuf, int recvbuflen) 
{ 
    if(out.is_open()) 
    { 
      out.write(recvbuf,recvbuflen); 
      ZeroMemory(&recvbuf,recvbuflen); 
    } 
}