#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib,"WS2_32.lib")
char buff[4004]; //接收文件缓冲区
FILE * wFile = NULL; //分割临时文件
FILE * nFile = NULL; //传输产生文件
char filename[20]; //分割临时文件名
int num =0; //记录接收文件个数
char newfilename[20];
struct RECVPARAM //线程回调函数参数
{
SOCKET socket;
// sockaddr_in Addr;
};
//线程回调函数
static DWORD WINAPI RecvProc(LPVOID lpParam)
{
char szchar[40];
int ch=0;
char ipaddress[40];
printf("请输入请求服务器的ip地址,例:127.0.0.1\n服务器ip:");
scanf("%s",ipaddress);
printf("请输入下载文件的路径及名称,例:d:\\a.jpg\n下载文件路径名称:");
scanf("%s",szchar);
printf("请输入存储文件的路径及名称,例:d:\\b.jpg\n存储文件路径名称:");
scanf("%s",newfilename);
/* for( int i = 0; (i < 39) && (ch != '\n'); i++ )
{
ch=getchar();
szchar[i] = (char)ch;
}
szchar[i]='\0';
*/
SOCKET sock=((RECVPARAM*)lpParam)->socket;
//欲发送主机ip、port
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(8888);
servAddr.sin_addr.S_un.S_addr = inet_addr(ipaddress);
int nAddrLen = sizeof(servAddr);
int numberbytes = ::sendto(sock, szchar, strlen(szchar)+1, 0, (SOCKADDR*)&servAddr, sizeof(SOCKADDR));
if(numberbytes == SOCKET_ERROR )
{
printf("send error!");
::WSACleanup();
return 0;
}
printf("正在等待接收文件...\n");
::CreateDirectory("d:\\temp", NULL);
while(TRUE)
{
::recvfrom(sock, buff, 4004, 0, (SOCKADDR*)&servAddr, &nAddrLen);
if(buff[0] =='j' && buff[1] =='p' && buff[2] =='g')
{
printf("已接收到数据包%d\n", buff[3]);
sprintf(filename, "d:\\temp\\%d", buff[3]);
wFile = fopen(filename, "wb");
if(!wFile)
{
::MessageBox(NULL, "打开文件失败!", 0, 0);
}
fwrite(buff+4, sizeof(char), 4000, wFile);
fclose(wFile);
num++;
}
else if(buff[0] == 'e' && buff[1] == 'n' && buff[2] == 'd' )
{
printf("服务器传送结束!共发送%d个数据包!",buff[3]);
break;
}
else printf("接收到错误数据包!\n");
}
}
int main(int argc,char *argv[])
{
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2,0);
::WSAStartup(sockVersion, &wsaData);
// 创建套接字
SOCKET s = ::socket(AF_INET, SOCK_DGRAM,0);
if(s == INVALID_SOCKET)
{
printf("Failed socket()\n");
::WSACleanup();
return 0;
}
/* printf("是否向服务器请求下载文件(y?n)");
char whether;
scanf("%c", &whether);
if(whether !='y')
{
::WSACleanup();
return 0;
}*/
//初始化线程回调函数的参数
RECVPARAM *pRecvParam=new RECVPARAM;
pRecvParam->socket=s;
// pRecvParam->Addr=servAddr;
HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
::WaitForSingleObject(hThread,40000);
::CloseHandle(hThread);
//合并接收到的分割文件
nFile = fopen(newfilename, "wb");
if(!nFile)
{
printf("打开接收文件失败!");
return 0;
}
for(int j = 1; j <= num; j++)
{
sprintf(filename, "d:\\temp\\%d", j);
wFile = fopen(filename, "rb");
if(!wFile)
{
printf("d:\\temp\\%d.jpg文件打开失败!",j);
//::MessageBox(NULL, "打开文件失败", 0, 0);
}
fread(buff, sizeof(char), 4000, wFile);
fwrite(buff, sizeof(char), 4000, nFile);
fclose(wFile);
::DeleteFile(filename);
}
fclose(nFile);
::closesocket(s);
::WSACleanup();
return 0;
}