⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.cpp

📁 WIN32API+WinSocket文件传输,文件传送程序源码
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////
//Developed by czk
//Ver: 0.1
//////////////////////////////////////////////////////////////////////////
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <windows.h>
#include <stdio.h> 
#include <tchar.h>

#include "resource.h"
#include "test.h"

BOOL CALLBACK  FileTranDlgProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
	if(-1 ==DialogBox(hInstance, TEXT("FileTranDlg"), NULL, FileTranDlgProc))
		MessageBox(NULL, "程序运行失败", "没办法", MB_OK);

	return 0;
}

BOOL CALLBACK  FileTranDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HWND hwndSendip, hwndRcvip, hwndText;
	static TCHAR lpstrFileName[MAX_PATH];
	static HANDLE hFileSend, hFileRecv;
	static FileInfo fileinfo;
	static unsigned int IPRcvFrom, IPSendTo;
	static int iError;	
	int		length;
	WORD    wEventS;
	switch(message)
	{
	case WM_INITDIALOG:
		InitOFN(hwnd);
		hwndSendip = GetDlgItem(hwnd, IDC_SENDip);
		hwndRcvip = GetDlgItem(hwnd, IDC_RCVip);
		hwndText = GetDlgItem(hwnd, IDC_TEXT);
		SetFocus(hwndSendip);
		return FALSE;
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDC_SEND:
			if((length = GetIPaddr(hwndSendip, &IPSendTo))<0)
				return TRUE;
			hFileSend = ReadyForSend(lpstrFileName, &fileinfo);
			if(hFileSend == INVALID_HANDLE_VALUE)
			{
				MessageBoxPrintf("Open File failed", "%s", "open file failed open file failed");
				return TRUE;
			}
			StartSendSocket(hwnd, hwndText, hFileSend, &IPSendTo);
			return TRUE;
		case IDC_RCV:
			if((length = GetIPaddr(hwndRcvip, &IPRcvFrom))<0)
				return TRUE;
			StartListenSocket(hwnd, hwndText);
			return TRUE;
		}
		break;
	case WM_SOCKET_send:
		wEventS = WSAGETSELECTEVENT (lParam);   // ie, LOWORD
		switch(wEventS)
		{
		case FD_WRITE:
			SendData(sendfd, hFileSend, hwndText, &fileinfo, lParam, hwnd);
			break;
		case FD_READ:
			FileInfoAccS(hwnd);
			break;
		}
		break;
	case WM_SOCKET_acc:
		StartAcceptSocket(lParam, &IPRcvFrom, hwndText, hwnd);//由返回值进行错误检测
		break;
	case WM_SOCKET_rcv:
		RecvData(hwndText, lpstrFileName, hFileRecv, lParam, hwnd);
		break;
	case WM_SYSCOMMAND:
        switch (LOWORD (wParam))
        {
        case SC_CLOSE:
			closesocket(sendfd);
			if(hFileSend)
			{
				CloseHandle(hFileSend);
				hFileSend = NULL;
			}
            WSACleanup();
            EndDialog(hwnd, 0);
            return TRUE;
        }
        break ;
	}

	return FALSE;
}

int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, ...)
{
     TCHAR   szBuffer[1024] ;
     va_list pArgList ;
     va_start (pArgList, szFormat) ;
     _vsntprintf (szBuffer, sizeof (szBuffer) / sizeof (TCHAR), 
                  szFormat, pArgList) ;
     va_end (pArgList) ;
     return MessageBox (NULL, szBuffer, szCaption, 0) ;
}

void EditPrintf (HWND hwndEdit, TCHAR * szFormat, ...)
{
     TCHAR   szBuffer [1024] ;
     va_list pArgList ;

     va_start (pArgList, szFormat) ;
     wvsprintf (szBuffer, szFormat, pArgList) ;
     va_end (pArgList) ;

     SendMessage (hwndEdit, EM_SETSEL, (WPARAM) -1, (LPARAM) -1) ;
     SendMessage (hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) szBuffer) ;
     SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0) ;
}


void InitOFN(HWND hwndDlg)
{
	static TCHAR szFilter[] = TEXT("All Files(*.*)\0*.*\0") \
							 TEXT("Text Files(*.TXT)\0*.txt\0\0");

	ofn.lStructSize       = sizeof(OPENFILENAME);
	ofn.hwndOwner         = hwndDlg;
	ofn.hInstance         = NULL;
	ofn.lpstrFilter       = szFilter;
	ofn.lpstrCustomFilter = NULL;
	ofn.nMaxCustFilter    = 0;
	ofn.nFilterIndex      = 0;
	ofn.lpstrFile         = NULL;
	ofn.nMaxFile          = MAX_PATH;
	ofn.lpstrFileTitle    = NULL;
	ofn.nMaxFileTitle     = MAX_PATH;
	ofn.lpstrInitialDir   = NULL;
	ofn.lpstrTitle        = NULL;
	ofn.Flags             = 0;        
	ofn.nFileOffset       = 0;
	ofn.nFileExtension    = 0;
	ofn.lpstrDefExt       = NULL;
	ofn.lCustData         = 0L;
	ofn.lpfnHook          = NULL;
	ofn.lpTemplateName    = NULL;
}

HANDLE ReadyForSend(PTSTR lpstrFileName, FileInfo *pfileinfo)
{
	HANDLE hFileSend;
	ofn.lpstrFile = lpstrFileName;
	ofn.lpstrFileTitle = pfileinfo->filename;
	ofn.Flags	  = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY;
	ofn.lpstrTitle=TEXT("发送文件");
	GetOpenFileName(&ofn);

	hFileSend = CreateFile(ofn.lpstrFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	pfileinfo->filesize = GetFileSize(hFileSend, NULL);

	return hFileSend;
}

BOOL StartSendSocket(HWND hwnd, HWND hwndText, HANDLE hFileSend, unsigned int *IP)
{
	WSADATA WSAData;
	WORD   iError;
	if(WSAStartup(WINSOCK_VERSION, &WSAData))
	{
		EditPrintf(hwndText, TEXT("%s"), TEXT("Sorry, Start WinSock Failed"));
		CloseHandle(hFileSend);
		hFileSend = NULL;
		return TRUE;
	}

	EditPrintf(hwndText, TEXT("Started up %hs"), WSAData.szDescription);

	memset(&SendTo, 0, sizeof(SendTo));
	SendTo.sin_family = AF_INET;
	SendTo.sin_addr.S_un.S_addr = (*IP);
	SendTo.sin_port = htons(8888);

	if((sendfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		EditPrintf(hwndText, TEXT("\r\n%s"), TEXT("Create Socket Error"));
		if(hFileSend)
		{
			CloseHandle(hFileSend);
			hFileSend = NULL;
		}
		WSACleanup();
		return TRUE;
	}
	EditPrintf(hwndText, TEXT("\r\nSocket %i created."), sendfd);
	if(SOCKET_ERROR == WSAAsyncSelect (sendfd, hwnd, WM_SOCKET_send, FD_WRITE|FD_READ))
    {
        EditPrintf(hwndText, TEXT ("\r\nWSAAsyncSelect error #%i."),WSAGetLastError ());
        closesocket(sendfd);
		if(hFileSend)
		{
			CloseHandle(hFileSend);
			hFileSend = NULL;
		}
        WSACleanup();
        return TRUE;
    }
	connect(sendfd, (SOCKADDR *)&SendTo, sizeof(SendTo));
    if(WSAEWOULDBLOCK != (iError = WSAGetLastError ()))
    {
        EditPrintf(hwndText, TEXT("\r\nConnect error #%i."), iError);
        closesocket(sendfd);
		if(hFileSend)
		{
			CloseHandle(hFileSend);
			hFileSend = NULL;
		}
        WSACleanup();
        return TRUE;
    }
    EditPrintf(hwndText, TEXT("\r\nConnecting to %hs..."), inet_ntoa(SendTo.sin_addr));

	return TRUE;
}

void ErrorHandle(SOCKET sock, HANDLE handle, HWND hwndText)
{
	if( INVALID_SOCKET != sock )
		closesocket(sock);
	if( INVALID_HANDLE_VALUE == handle )
		CloseHandle(handle);
	WSACleanup();
}

int SendData(SOCKET sendfd, HANDLE hFileSend, HWND hwndText, FileInfo *pfileinfo, LPARAM lParam, HWND hwnd)
{
	static char *SendBuf;
	static DWORD  TotalInfoLen = 0;
	static DWORD  TotalLen = 0;
	static DWORD  Len = 0;
	static DWORD  nIn;
	static DWORD  size;
	static BOOL First = TRUE;

	int  oncelen;	
	WORD wEvent, wError;

	wEvent = WSAGETSELECTEVENT (lParam);   // ie, LOWORD
    wError = WSAGETSELECTERROR (lParam);   // ie, HIWORD
	if( wError || FD_WRITE != wEvent )
	{
		EditPrintf(hwndText, TEXT("\r\n%s"), TEXT("网络事件错误,文件发送失败"));
		ErrorHandle(sendfd, hFileSend, hwndText);
		return -1;
	}
	if(First)
	{
		EditPrintf(hwndText, TEXT("\r\n开始发送数据 ..... "));
		First = FALSE;
	}
	while(TotalInfoLen<sizeof(FileInfo))	//if(First)
	{	
		pfileinfo->filesize = htonl(pfileinfo->filesize);
		oncelen = send(sendfd, ((char *)pfileinfo+TotalInfoLen), (sizeof(FileInfo)-TotalInfoLen), 0);
		if(oncelen<0)
			return oncelen;
		TotalInfoLen += oncelen;
		if(TotalInfoLen == sizeof(FileInfo))
		{
			size = ntohl(pfileinfo->filesize);
			SendBuf = (char *)xmalloc(MIN(size,MAX_malloc));
			ReadFile(hFileSend, SendBuf, MIN(size,MAX_malloc), &nIn, NULL);
			break;
		}
	}
	if(!peer)
		return 1;
	while(TotalLen<size)	//else
	{
		while(Len<nIn)
		{
			oncelen = send(sendfd, (SendBuf+Len), MIN(4400, nIn-Len), 0);
			if(oncelen<0)
				return oncelen;
			Len += oncelen;
			TotalLen += oncelen;
		}
		if(TotalLen == size)
		{
			EditPrintf(hwndText, TEXT("\r\n文件已经发送完毕,共 %i 字节"), size);
			WSAAsyncSelect (sendfd, hwnd, 0, 0);
			xfree(SendBuf);
			closesocket(sendfd);
			CloseHandle(hFileSend);
			WSACleanup();
			TotalInfoLen = 0; TotalLen = 0; Len = 0; nIn = 0; size = 0;
			return 1;
		}
		if(ReadFile(hFileSend, SendBuf, MAX_malloc, &nIn, NULL) && (nIn>0))
		{
			Len = 0;
		}
	}
	return 1;
}

int GetIPaddr(HWND hwnd, unsigned int *IP)
{
	int iLength;
	unsigned int ip;
	TCHAR szIP[20];
	iLength = SendMessage(hwnd, EM_GETLINE, 0, (LPARAM)szIP);
	iLength = strlen(szIP);
	szIP[iLength+1] = '\0';
	ip = inet_addr(szIP);
	if(iLength<7 || (INADDR_NONE==ip))
	{
		MessageBoxPrintf(TEXT("Error"), TEXT("请输入正确的 IP 地址"));
		return -1;
	}
	
	*IP = ip;
	return iLength;
}

int StartListenSocket(HWND hwndMain, HWND hwndText)
{
	int  iError;
	WSADATA WSAData;
	EditPrintf(hwndText, TEXT("\r\n%s"), TEXT("正在开启监听套接口....."));
	if(iError = WSAStartup(WINSOCK_VERSION, &WSAData))
    {
         EditPrintf (hwndText, TEXT("\r\nStartup error #%i."), iError);
         return iError;
    }
    rcvfd = socket(AF_INET, SOCK_STREAM, 0);
    if(rcvfd == INVALID_SOCKET)
    {
         EditPrintf(hwndText, TEXT("\r\nSocket creation error #%i."), WSAGetLastError());
         WSACleanup();
         return INVALID_SOCKET;
    }
    EditPrintf(hwndText, TEXT("\r\nSocket %i created."), rcvfd);
    if(SOCKET_ERROR == WSAAsyncSelect(rcvfd, hwndMain, WM_SOCKET_acc, FD_ACCEPT))
    {
         EditPrintf (hwndText, TEXT("**WSAAsyncSelect error #%i.\r\n"),WSAGetLastError());
         closesocket(rcvfd);
         WSACleanup();
         return SOCKET_ERROR;
    }

    memset(&RcvFrom, 0, sizeof(RcvFrom));
	RcvFrom.sin_family           = AF_INET ;
    RcvFrom.sin_port             = htons(8888); 
    RcvFrom.sin_addr.S_un.S_addr = INADDR_ANY;
	if(bind(rcvfd, (struct sockaddr *)&RcvFrom, sizeof(RcvFrom)) == SOCKET_ERROR)
	{
		EditPrintf(hwndText, TEXT("\r\nbind error: %d"), WSAGetLastError());
		closesocket(rcvfd);
		WSACleanup();
		return SOCKET_ERROR;
	}
	if(listen(rcvfd, 1) == SOCKET_ERROR)
	{
		EditPrintf(hwndText, TEXT("\r\nlisten error: %d"), WSAGetLastError());
		closesocket(rcvfd);
		WSACleanup();
		return SOCKET_ERROR;
	}
	EditPrintf(hwndText, TEXT("\r\n%s"), TEXT("正在监听连接...."));

	return 1;
}

int StartAcceptSocket(LPARAM lParam, unsigned int *IP, HWND hwndText, HWND hwndMain)
{
	struct sockaddr_in peerSockaddr;
	int   SockAddrLen = sizeof(peerSockaddr);
	WORD  wEvent, wError;
	wEvent = WSAGETSELECTEVENT (lParam);   // ie, LOWORD
	wError = WSAGETSELECTERROR (lParam);   // ie, HIWORD
	if(wError || (wEvent!=FD_ACCEPT))
	{
		EditPrintf(hwndText, TEXT("\r\n%s"), TEXT("接受连接发生错误"));
		closesocket(rcvfd);
		WSACleanup();
		return wError;
	}
	acceptfd = accept(rcvfd, (struct sockaddr *)&peerSockaddr, &SockAddrLen);
	if(INVALID_SOCKET == acceptfd)
	{
		EditPrintf(hwndText, TEXT("\r\naccept error %i."), WSAGetLastError());
		closesocket(acceptfd);
		return SOCKET_ERROR;
	}
	if(SOCKET_ERROR == WSAAsyncSelect(acceptfd, hwndMain, WM_SOCKET_rcv, FD_READ))
	{
		EditPrintf(hwndText, TEXT ("\r\nWSAAsyncSelect error #%i."),WSAGetLastError());
		closesocket(acceptfd);
		WSACleanup();
		return SOCKET_ERROR;
	}
	if( (*IP) != peerSockaddr.sin_addr.S_un.S_addr )
	{
		EditPrintf(hwndText, TEXT("\r\n非指定地址的连接到来,关闭连接"));
		WSAAsyncSelect (acceptfd, hwndMain, 0, 0);
		closesocket(acceptfd);
		return -2;
	}
	WSAAsyncSelect(rcvfd, hwndMain, 0, 0);
	closesocket(rcvfd); //现在只要保留acceptfd即可
	EditPrintf(hwndText, TEXT("\r\n接收数据的连接已经建立"));

	return 1;
}

int RecvData(HWND hwndText, TCHAR *lpstrFileName, HANDLE &hFileRcv, LPARAM lParam, HWND hwnd)
{
	static unsigned int   FileInfoLen = sizeof(FileInfo);
	static unsigned int TotalInfoRecvd = 0;
	static unsigned int TotalFileRecvd = 0;
	static unsigned int  ThisTotalLen = 0;
	static FileInfo fileinfo;
	static char *RecvBuf;
	static BOOL First = TRUE;
	
	int  oncelen;
	DWORD  nOut;
/*	WORD  wEvent, wError;

	wEvent = WSAGETSELECTEVENT (lParam);   // ie, LOWORD
	wError = WSAGETSELECTERROR (lParam);   // ie, HIWORD
	if(wError || (wEvent!=FD_READ))
	{
		EditPrintf(hwndText, TEXT("\r\n%s"), TEXT("接收数据发生错误"));
		closesocket(rcvfd);
		WSACleanup();
		return wError;
	}
*/	if(First)
	{
		EditPrintf(hwndText, TEXT("\r\n开始接收数据 ..... "));
		First = FALSE;
	}
	while(TotalInfoRecvd < FileInfoLen)
	{
		oncelen = recv(acceptfd, (char *)&fileinfo, FileInfoLen, 0);
		if(oncelen<0)
			return -1;
		TotalInfoRecvd += oncelen;
		if(TotalInfoRecvd == FileInfoLen)
		{
			fileinfo.filesize = ntohl(fileinfo.filesize);
			ofn.lpstrFile = fileinfo.filename;
			ofn.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
			ofn.lpstrTitle = TEXT("将接收文件保存为");
			GetSaveFileName(&ofn);
			//如果文件已经存在则CreateFile调用失败
			hFileRcv = CreateFile(ofn.lpstrFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
			RecvBuf = (char *)xmalloc(MAX_malloc);
			FileInfoAccR(hwnd);
		}
	}
	while(TotalFileRecvd < fileinfo.filesize)
	{
		while(ThisTotalLen < MIN(MAX_malloc, fileinfo.filesize-TotalFileRecvd))
		{
			oncelen = recv(acceptfd, RecvBuf + ThisTotalLen, MAX_malloc - ThisTotalLen, 0);
			if(oncelen < 0)
				return -1;
			ThisTotalLen += oncelen;
			TotalFileRecvd += oncelen;
		}
		WriteFile(hFileRcv, RecvBuf, ThisTotalLen, &nOut, NULL);
		if( nOut != ThisTotalLen )
		{
			EditPrintf(hwndText, TEXT("\r\nFatal write error: %x"), GetLastError());
			//.........
		}
		ThisTotalLen = 0;
		if(TotalFileRecvd == fileinfo.filesize )
		{
			EditPrintf(hwndText, TEXT("\r\n文件接收完毕,共 %i 字节"), fileinfo.filesize);
			EditPrintf(hwndText, TEXT("\r\n文件已保存为 %s"),fileinfo.filename);
			xfree(RecvBuf);
			RecvBuf = NULL;
			CloseHandle(hFileRcv);
			closesocket(acceptfd);
			WSACleanup();
		}
	}
	if(TotalFileRecvd == fileinfo.filesize)
	{
		TotalFileRecvd = 0;
		TotalInfoRecvd = 0;
		ThisTotalLen = 0;
	}
	return 1;
}

int FileInfoAccS(HWND hwnd)
{
	AccInfo accinfo;
	recv(sendfd, (char *)&accinfo, sizeof(accinfo), 0);
	if( accinfo.info[0]=='w')
	{
		peer = TRUE;
		WSAAsyncSelect(sendfd, hwnd, WM_SOCKET_send, FD_WRITE);
	}
	else
		return -1;
	return 1;
}

int FileInfoAccR(HWND hwndMain)
{
	AccInfo accinfo;
	accinfo.info[0]='w'; accinfo.info[1]='a'; accinfo.info[2]='n'; accinfo.info[3]='\0';//
	send(acceptfd, (char *)&accinfo, sizeof(accinfo), 0);
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -