}void CTransferDlg::OnConnect() { // TODO: Add your control notification handler code here clientsocket.Create(); clientsocket.Connect("127.0.0.1",7000);
} // MySocket.cpp : implementation file CMySocket serversocket; CMySocket clientsocket; void CMySocket::OnAccept(int nErrorCode) { // TODO: Add your specialized code here and/or call the base class
if(!serversocket.Accept(clientsocket)) { AfxMessageBox("连接失败"); return; } AfxMessageBox("连接成功"); CAsyncSocket::OnAccept(nErrorCode);} 其中CMySocket class CMySocket : public CAsyncSocket不知道为什么会这样,大家帮我看看,给我指点一下吧,谢谢!
看来你需要一个网络通讯协议,我给你定义一个看下面: head(1) findex(2) dindex(2) flag(1) date(1024-1-2-2-1-1) end(1) INF n 0 1 (文件名字) OVE BEG n 0 0 NULL OVE DAT n 0+x 1 (文件片段) OVE NEX n 0+x 0 NULL OVE END n 0 1 (文件长度) OVE 通讯应答模式: 发起端 接收端 通知------INF------------------->准备接收文件(创建文件)注意记录findex <=============BEG===============准备完成 生成第一个包-------DAT--------->根据findex找到文件,保存(文件片段) <============NEX===============保存完毕要求发送第二个包dindex为接收的序号 生成第二个包-------DAT--------->根据findex找到文件,保存(文件片段) <===========NEX================保存完毕要求发送第三个包dindex为接收的序号 当文件发送完毕以后----END------>查看接受文件长度如果相等表示文件接收成功 一定要注意findex(表示文件序号),和dindex(表示文件片段序号) INF、BEG、DAT等的定义如:#define INF 0x01 注意一个包可以是1024个字节,也可以更大或着更小,看你的文件而定 int CMyMsg::MakePackage(BYTE head,int findex, int dindex, char flag, char *data) { char temp[1024]; int len=0; temp[0]=head;//添加头 memcpy(&temp[1],&findex,2);//序号 memcpy(&temp[3],&dindex,2); temp[5]=flag;//数据有效位 if (datain==1)//表示数据data有效 { len=_mbstrlen(data);//获得数据长度 memcpy(&temp[6],data,len);//拷贝数据 } temp[len+6]=(BYTE)OVE;//添加尾 memset(data,'\0',1024);//清空指针 memcpy(data,temp,len+6);//返回帧return len+6; }(打包函数)读取文件的时候注意包的总长度,如果是1024读取的文件长度为1024-6
[email protected]
[email protected]
tcp的话,就在一个程序里自己连接自己就可以了。
upd就更简单,直接发送到你的程序的接收端口,不就可以了吗?
合并后的程序为Transfer.exe,不妨称为:A和B,
我启动了两个程序,A侦听,B连接“127.0.0.1”,连接成功
如果先让A向B传文件,则B可以成功接受,
但一旦让B向A传文件,则A无法成功接受,并且此后A再向B传,B也无法成功接受。
反过来也是一样,即:
如果先让B向A传文件,则A可以成功接受,
但一旦让A向B传文件,则B无法成功接受,并且此后B再向A传,A也无法成功接受。我把关键代码帖出来,大家帮我看看吧:
// TransferDlg.cpp : implementation file
#define ReadSize 500
#include "MySocket.h"
extern CMySocket serversocket;
extern CMySocket clientsocket;void CTransferDlg::OnSend()
{
// TODO: Add your control notification handler code here
CFile file;
char data[ReadSize]; // 用于存放读入的文件数据块
long ByteSended=0, FileLength,count;
CFileDialog fd(TRUE);
CString filename;
char fn[40];
if(IDOK==fd.DoModal()) // 启动用于选择文件的对话框
{
//选择了文件
filename=fd.GetFileName(); //获取选择的文件的文件名
if(!file.Open(
filename.GetBuffer(0),CFile::modeRead|CFile::typeBinary))
{
AfxMessageBox("打开文件错误,取消发送!");
return;
}
strcpy(fn,filename.GetBuffer(0));
}
else return; //按了取消按钮
FileLength=file.GetLength();
clientsocket.Send(&FileLength,sizeof(long));
clientsocket.Send(fn,40);
memset(data,0,sizeof(data));
do{
// 从文件读取数据,每次最多读入ReadSize个字节。
//count表示实际读入的字节数
ount=file.ReadHuge(data, ReadSize);
// 发送数据
while(SOCKET_ERROR == clientsocket.Send(data,count))
{
}
// 统计已发送的字节数
ByteSended = ByteSended + count;
}while(ByteSended < FileLength);
file.Close();}void CTransferDlg::OnListen()
{
// TODO: Add your control notification handler code here
serversocket.Create(7000);
serversocket.Listen();
}void CTransferDlg::OnReceive()
{
// TODO: Add your control notification handler code here
CFile file;
char data[ReadSize];
long FileLength;
long WriteOnce;
long WriteCount = 0;
char fn[40]; // 接收文件长度
while(SOCKET_ERROR == clientsocket.Receive(&FileLength,sizeof(long)))
{
}
// 接收文件名
while(SOCKET_ERROR == clientsocket.Receive(fn,40))
{
}
if(!file.Open(fn,CFile::modeCreate|CFile::modeWrite))
{
AfxMessageBox("Create file error!");
return;
}
do{
WriteOnce = clientsocket.Receive(data,ReadSize);
if(WriteOnce == SOCKET_ERROR)
continue;
// 统计已接受的字节数
WriteCount=WriteCount+WriteOnce;
// 把收到的数据写入文件
file.WriteHuge(data,WriteOnce);
}while(WriteCount< FileLength);
file.Close();
AfxMessageBox("接收文件成功");
}void CTransferDlg::OnConnect()
{
// TODO: Add your control notification handler code here clientsocket.Create();
clientsocket.Connect("127.0.0.1",7000);
}
// MySocket.cpp : implementation file
CMySocket serversocket;
CMySocket clientsocket;
void CMySocket::OnAccept(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
if(!serversocket.Accept(clientsocket))
{
AfxMessageBox("连接失败");
return;
}
AfxMessageBox("连接成功");
CAsyncSocket::OnAccept(nErrorCode);}
其中CMySocket
class CMySocket : public CAsyncSocket不知道为什么会这样,大家帮我看看,给我指点一下吧,谢谢!
如果先让A向B传文件,则B可以成功接受;
但一旦让B向A传文件,则A无法成功接受,但是在这里,
我用AfxMessageBox(fn);来看看是否接收到了文件名,奇怪的是,文件名竟然都接收到了,
并且了最后的“接收文件成功"都显示出来了,可就是在文件夹里看不到接收的文件,很奇怪,我都晕死了。
head(1) findex(2) dindex(2) flag(1) date(1024-1-2-2-1-1) end(1)
INF n 0 1 (文件名字) OVE
BEG n 0 0 NULL OVE
DAT n 0+x 1 (文件片段) OVE
NEX n 0+x 0 NULL OVE
END n 0 1 (文件长度) OVE
通讯应答模式:
发起端 接收端
通知------INF------------------->准备接收文件(创建文件)注意记录findex
<=============BEG===============准备完成
生成第一个包-------DAT--------->根据findex找到文件,保存(文件片段)
<============NEX===============保存完毕要求发送第二个包dindex为接收的序号
生成第二个包-------DAT--------->根据findex找到文件,保存(文件片段)
<===========NEX================保存完毕要求发送第三个包dindex为接收的序号
当文件发送完毕以后----END------>查看接受文件长度如果相等表示文件接收成功
一定要注意findex(表示文件序号),和dindex(表示文件片段序号)
INF、BEG、DAT等的定义如:#define INF 0x01
注意一个包可以是1024个字节,也可以更大或着更小,看你的文件而定
int CMyMsg::MakePackage(BYTE head,int findex, int dindex, char flag, char *data)
{
char temp[1024];
int len=0;
temp[0]=head;//添加头
memcpy(&temp[1],&findex,2);//序号
memcpy(&temp[3],&dindex,2);
temp[5]=flag;//数据有效位
if (datain==1)//表示数据data有效
{
len=_mbstrlen(data);//获得数据长度
memcpy(&temp[6],data,len);//拷贝数据
}
temp[len+6]=(BYTE)OVE;//添加尾
memset(data,'\0',1024);//清空指针
memcpy(data,temp,len+6);//返回帧return len+6;
}(打包函数)读取文件的时候注意包的总长度,如果是1024读取的文件长度为1024-6
www.vckbase.com/code
我打成包CMyMsg之后该怎么传啊?还是用clientsocket.Send,clientsocket.Receive传吧,
怎么就知道用了这个就不会碰到我原来的哪些问题呢?
{
char temp[1024];
int len=0;
MYNUM num;
temp[0]=flag;//添加头
num.num=Link;
memcpy(&temp[1],num.ch,4);
num.num=index;
memcpy(&temp[5],num.ch,4);//序号
temp[9]=datain;//数据有效位
if (datain==1)//表示数据data有效
{
len=_mbstrlen(data);//获得数据长度
memcpy(&temp[10],data,len);//拷贝数据
}
temp[len+10]=(BYTE)OVE;//添加尾
memset(data,'\0',1024);//清空指针
memcpy(data,temp,len+10);//返回帧return len+10;
}这个是我修改以后的打包函数,原来的有点问题,MYNUM 是一个共用体定义为
union MYNUM{
char ch[4];
int num;
};
这个函数的data参数传进来的是你需要传送的文件片段,打包完成以后整个包的数据就在data中你传送的时候只要Send(data,len)len是函数返回的长度
你解包的时候用一个switch语句.你是在OnReceive中Receive的吧!如果你把接收的数据保存在char buf[1024]中那么你的switch应该是这样
switch(buf[0])
{
case INF:
break;
case BEG:
break;
......
}在case语句中完成我给你的协议中的工作就可以了
说到这里了,如果还不行!!!!我一头装在墙上了
这个协议完全可以解决你的问题!我现在用的协议也跟这个差不多,只不过比这个麻烦一点!因为我要支持30个客户端的通讯,包括文件传送,和一般消息传送!!