请各位看看: 用 winsock 传送接收文件,接收到的文件数据与原文件不同,不知是何原因.附详细原码.

lner 2002-05-31 10:39:56
/////////////////////////////////////////
服务端: (接收文件)

#include "stdafx.h"

BOOL g_bWorking;

CListBox* g_log = NULL;
const UINT nPacketSize = 1024*4 ;

UINT ServiceThreadProc(LPVOID pParam)
{
SOCKET clientsocket = (SOCKET) pParam;
BOOL bOk = FALSE;
char filenamelen[4]; // int
char filelength[32]; // dword

recv(clientsocket, filenamelen, 4, 0); // receive filename length
char* filename = (char*)malloc(atoi(filenamelen));


recv(clientsocket, filename, atoi(filenamelen), 0); // receive filename

recv(clientsocket, filelength, 32, 0); // receive file length

int nLen = atoi(filelength);


byte* data;



HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING, NULL);

if (hFile == INVALID_HANDLE_VALUE)
bOk = FALSE;
else
bOk = TRUE;

DWORD writeSize;
if (bOk) {
while (nLen > 0) {

if (nLen >= nPacketSize) {
data = new byte[nPacketSize];

if( recv(clientsocket, (char*)data, nPacketSize, 0) == SOCKET_ERROR)
AfxMessageBox("socket error");

WriteFile(hFile, data, nPacketSize, &writeSize, NULL);
nLen -= nPacketSize;
}
else {
data = new byte[nLen];

if (recv(clientsocket, (char*)data, nLen, 0) == SOCKET_ERROR)
AfxMessageBox("socket error");

WriteFile(hFile, data, nLen, &writeSize, NULL);
nLen = 0;
}
} // End while

FlushFileBuffers(hFile);
CloseHandle(hFile);
}
else {
AfxMessageBox("open file fail");
}


AfxMessageBox("receive complete");

closesocket(clientsocket);
free(filename);

return 0;
};

UINT ServerThreadProc(LPVOID pParam)
{
//初始化TCP协议
SOCKET serversocket;
WSADATA wsaData ;
BOOL ret = WSAStartup(MAKEWORD(1,1), &wsaData);
if (ret != 0) {
AfxMessageBox("初始化套接字失败!");
return 1;
}

//创建服务器端套接字
serversocket = socket(AF_INET, SOCK_STREAM, 0); //IPPROTO_TCP
if (serversocket == INVALID_SOCKET) {
AfxMessageBox("创建套接字失败!");
closesocket(serversocket);
WSACleanup();
return 2;
}

//绑定到本地一个端口上
sockaddr_in localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(1234);
localaddr.sin_addr.s_addr = INADDR_ANY; // OR
//localaddr.sin_addr.s_addr = inet_addr("192.168.0.1") ;

if (bind(serversocket, (const struct sockaddr*) & localaddr,
sizeof(localaddr)) == SOCKET_ERROR)
{
AfxMessageBox("绑定地址失败!");
closesocket(serversocket);
WSACleanup();
return 3;
}

listen(serversocket, 5); //设置侦听模式

g_bWorking = TRUE;
int len = sizeof(sockaddr);
sockaddr_in clientaddr;




while (g_bWorking) {
SOCKET client = accept(serversocket, (struct sockaddr*)&clientaddr, &len);
AfxBeginThread(ServiceThreadProc, (LPVOID)client, THREAD_PRIORITY_NORMAL);
}

return 0;
};

//////////////////////////////////////////////////////////////////

客户端:(发送文件)

void CTcpClientDlg::OnbuttonConnect()
{

int result ;
WSADATA wsaData ;

//初始化TCP协议
BOOL ret = WSAStartup(MAKEWORD(1,1), &wsaData);
if (ret != 0) {
MessageBox("初始化套接字失败!");
return ;
}

//创建客户端套接字
m_clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_clientSocket == INVALID_SOCKET) {
MessageBox("创建套接字失败!");
closesocket(m_clientSocket);
WSACleanup();
return ;
}

struct sockaddr_in destaddr ;
destaddr.sin_family = AF_INET;
destaddr.sin_port = htons(1234);
destaddr.sin_addr.s_addr = inet_addr("192.168.0.1");

result = connect(m_clientSocket, (struct sockaddr *) & destaddr,sizeof(destaddr)) ;

if (result == SOCKET_ERROR) {
MessageBox("connect error");
return ;
}

//socket注册异步事件,注意没有Accept事件
if (WSAAsyncSelect(m_clientSocket ,m_hWnd, NETWORK_EVENT,
FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
{
MessageBox("(client)注册异步事件失败!");
return;
}

m_IsConnected = true ;

/////////////////////////////////////
char filenamelen[4];
char filelength[8];
char* filename = "lostinspace.mov";
CFile readFile;

CString echo;
const nPacketSize = 1024*4;

_itoa(strlen(filename), filenamelen, 10);
send(m_clientSocket, filenamelen, 4, 0); // send filename length
send(m_clientSocket, filename, strlen(filename), 0); // send filename


readFile.Open("E:\\lostinspace.mov", CFile::modeRead);
DWORD filelen = readFile.GetLength() ;
readFile.Close();

HANDLE hFile = CreateFile("E:\\lostinspace.mov", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);

//if (readFile.Open("E:\\lostinspace.mov", CFile::modeRead))
if (hFile != INVALID_HANDLE_VALUE) {

_itoa(filelen, filelength, 10);

send(m_clientSocket, filelength, 32, 0); // send file length
byte* data = NULL;
DWORD dwReaded;

while (filelen > 0) {

if (filelen >= nPacketSize) {
data = new byte[nPacketSize];
ReadFile(hFile, data, nPacketSize, &dwReaded, NULL);
send(m_clientSocket, (char*)data, nPacketSize, 0);
filelen = filelen - nPacketSize;
}
else {
data = new byte[filelen];
ReadFile(hFile, data, filelen, &dwReaded, NULL);
send(m_clientSocket, (char*)data, filelen, 0);
filelen = 0;
}
}

CloseHandle(hFile);
MessageBox("send complete.");

}
else {
MessageBox("Open file fail");
}

}

/////////////////////////////////////////////////
...全文
64 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
xlb2000 2002-05-31
  • 打赏
  • 举报
回复
要在接收数据和将数据写入文件之间设立缓冲区(如设一个数组),在数据全部接受完毕时,再将缓冲区的数据写入文件。不然的话,接收数据和写入文件常常不同步,如后者时间比前者长,赵成先到的数据被后来的数据覆盖而丢失数据
qiuanhong 2002-05-31
  • 打赏
  • 举报
回复

发过来,晚上跟你调试一下
dnetmaterial@sohu.com
wxfjb 2002-05-31
  • 打赏
  • 举报
回复
缩进不好,所以没有读你的代码。不过我用的是字符数组传送的。没有问题,在OnReceive()中调用接收函数并写入文件。
不过你似乎没有传送文件本身的信息。
SOCKET_STREAM_FILE_INFO StreamFileInfo;
WIN32_FIND_DATA FindFileData;

FindClose(FindFirstFile(Dlg.GetPathName(),&FindFileData));
memset(&StreamFileInfo,0,sizeof(SOCKET_STREAM_FILE_INFO));
strcpy(StreamFileInfo.szFileTitle,myFile.GetFileTitle());

StreamFileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
StreamFileInfo.ftCreationTime = FindFileData.ftCreationTime;
StreamFileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
StreamFileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
StreamFileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
StreamFileInfo.nFileSizeLow = FindFileData.nFileSizeLow;
xuying 2002-05-31
  • 打赏
  • 举报
回复
出什么错啊,说一下。
检查你的文件名,文件长度是否传送的正确。
lner 2002-05-31
  • 打赏
  • 举报
回复
另: 发送端发送时能连继发送数据,服务器常常是接收到一半就停顿了,当发送端发完,退出程序时,服务器再继续接收数据,不知什么原因
lner 2002-05-31
  • 打赏
  • 举报
回复
谢谢楼上的建议,如需源程序调试(谢谢你的帮助),请留下 email ,在线发送.

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧