关于CSocket的使用

panzhijiepanzhiyang 2010-04-25 10:20:59
关于CSocket经常使用的函数
还有怎样判断发过来的是字符串还是数字
是不是通过附加其他字符串来提示接受方
如果传文件应该怎样办
图片
如果有介绍这方面的好网站也可以
或者大家给几个简单的例子
...全文
356 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
howema 2010-04-26
  • 打赏
  • 举报
回复
肯定要自己判断的

文件传输网上有很多例子的 baidu
Eleven 2010-04-25
  • 打赏
  • 举报
回复
还是不要使用CSocket类了,自己从头写吧,这样的话socket流程会比较清晰。。。
尹成 2010-04-25
  • 打赏
  • 举报
回复
源文件

http://download.csdn.net/source/1096750
请参考
尹成 2010-04-25
  • 打赏
  • 举报
回复
//1:显示文件进度


//2:可以随时终止传输过程


//发送数据线程


UINT SendDataThread(LPVOID lpParam);


//接收数据线程


UINT ReceiveDataThread(LPVOID lpParam);


//发送数据按钮消息响应函数


void CTzg004Dlg::OnButtonSend()


{


// TODO: Add your control notification handler code here


//初始化数据发送结束标志


m_bSendEnd=FALSE;


//初始化数据接收结束标志


m_bRecEnd=FALSE;


//更新对话框数据


UpdateData(TRUE);


//打开文件对话框


CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,


"所有文件 (*.*)|*.*||");


if(dlg.DoModal()==IDOK)


{


m_strFileName=dlg.GetPathName();


//开始发送数据线程


AfxBeginThread(SendDataThread,this,THREAD_PRIORITY_NORMAL);


}


}


//接收数据按钮消息响应函数


void CTzg004Dlg::OnButtonReceive()


{


// TODO: Add your control notification handler code here


//初始化数据发送结束标志


m_bSendEnd=FALSE;


//初始化数据接收结束标志


m_bRecEnd=FALSE;


UpdateData(TRUE);


//开始接收数据线程


AfxBeginThread(ReceiveDataThread,this,THREAD_PRIORITY_NORMAL);


}


//终止发送按钮消息响应


void CTzg004Dlg::OnButtonSendEnd()


{


// TODO: Add your control notification handler code here


//设置发送数据结束标志


m_bSendEnd=TRUE;


}


//终止接收按钮消息响应


void CTzg004Dlg::OnButtonRecEnd()


{


// TODO: Add your control notification handler code here


//设置接收数据结束标志


m_bRecEnd=TRUE;


}


UINT SendDataThread(LPVOID lpParam)


{


CTzg004Dlg *pDlg=(CTzg004Dlg *)lpParam;


CFile file;


if( !file.Open(pDlg->m_strFileName, Cfile::modeRead) )


{


AfxMessageBox("打开文件出错!");


return 0;


}


CSocket sockTemp;


CString str,str1;


sockTemp.Create(pDlg->m_iDataPort1); //得到端口号


sockTemp.Listen(1);//只接受一个连接


CSocket sockSend;


//设置发送按钮禁止


pDlg->GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);


sockTemp.Accept(sockSend);//注意,sockTemp已交了自己的指针地址到sockSend,故不用Close


//打开发送终止按钮


pDlg->GetDlgItem(IDC_BUTTON_SEND_END)->EnableWindow(TRUE);








int iBufSize = 1024 * 5;


int iSize = iBufSize;


LPBYTE pBuf = new BYTE[iBufSize];





DWORD dwTemp = 0;


BOOL bTest = sockSend.AsyncSelect(0);//由于CSocket实际是异步,将它变为同步(阻塞)方式。


sockSend.IOCtl( FIONBIO, &dwTemp);//用IOCtl要将AsyncSelect的第一个参数为0,参看MSDN





UINT uiLength = file.GetLength();


sockSend.Send(&uiLength, 4);//传送文件大小到接收方(Client端)





int iNumByte;


UINT uiTotal = 0;


while(uiTotal < uiLength)


{


int iEnd=pDlg->m_bSendEnd;


//传送发送端状态(是否结束)


iNumByte = sockSend.Send(&iEnd, sizeof(int));


//发送错误


if(iNumByte == SOCKET_ERROR)


{


AfxMessageBox("发送错误!");


goto ExitLable1;


}else if(iEnd==1)//发送端终止


{


AfxMessageBox("发送端终止");


goto ExitLable1;


}


//读取文件内容


if((int)(uiLength - uiTotal) < iBufSize)


iSize = uiLength - uiTotal;//当小于缓冲区iTEST时的处理


iSize=file.Read(pBuf , iSize);//得到读取的字节数


int iCount=0;


//发送定长文件数据


while(iCount<iSize)


{


iNumByte = sockSend.Send(pBuf, iSize-iCount);//注意iNumByte为实际的发送字节数,不要以iSize为准


if(iNumByte == SOCKET_ERROR)


{


AfxMessageBox("发送错误!");


goto ExitLable1;


}


iCount+=iNumByte;


if(iCount<iSize)


{


file.Seek(iSize-iCount,Cfile::current);


}


}


uiTotal += iCount;


//设置发送数据进度条


pDlg->m_CtrlProgressSend.SetPos(int(((double)uiTotal/uiLength)*100));


str.Format("发送进度:%d%%",int(((double)uiTotal/uiLength)*100));


//表明发送数据百分比


pDlg->GetDlgItem(IDC_STATIC_SEND)->GetWindowText(str1);


if(str1!=str)


pDlg->GetDlgItem(IDC_STATIC_SEND)->SetWindowText(str);


}


//发送文件成功


AfxMessageBox("发送文件成功!");


ExitLable1:


delete[] pBuf;


file.Close();


sockSend.Close();


pDlg->m_CtrlProgressSend.SetPos(0);//恢复进度


pDlg->GetDlgItem(IDC_BUTTON_SEND_END)->EnableWindow(FALSE);//设置发送结束按钮禁止


pDlg->GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(TRUE);//设置发送按钮正常


pDlg->GetDlgItem(IDC_STATIC_SEND)->SetWindowText("发送进度:"); //恢复提示进度


return 0;


}



UINT ReceiveDataThread(LPVOID lpParam)


{


CTzg004Dlg *pDlg=(CTzg004Dlg *)lpParam;


//保存文件对话框


CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,


"所有文件 (*.*)|*.*||");


while(dlg.DoModal()!=IDOK)


{


AfxMessageBox("选择文件出错,请重新选择!");


}


CString str,str1,str2;


CSocket sockRecv;


sockRecv.Create();


pDlg->m_CtrlIPSend.GetWindowText(str);//得到发送端IP地址


pDlg->GetDlgItem(IDC_BUTTON_RECEIVE)->EnableWindow(FALSE);//禁止接收按钮


while(sockRecv.Connect(str,pDlg->m_iDataPort2)==0)//连接发送方地址,若上网,可改为实际IP地址,端口要跟Server端相同。


{


Sleep(50);


}


pDlg->GetDlgItem(IDC_BUTTON_REC_END)->EnableWindow(TRUE);//打开终止接收按钮


str2=dlg.GetPathName();//得到文件名


CFile file;


file.Open(str2, Cfile::modeCreate | Cfile::modeWrite);


BOOL bFileFail=FALSE;


DWORD dwTemp = 0;


sockRecv.AsyncSelect(0);


sockRecv.IOCtl( FIONBIO, &dwTemp);//变为阻塞方式





UINT uiLength;


sockRecv.Receive(&uiLength, 4);//接收发方(Server端)的文件大小


int iBufSize = 1024 * 5;


int iSize = iBufSize;


LPBYTE pBuf = new BYTE[iBufSize];


int iNumByte;


UINT uiTotal = 0;


while(uiTotal < uiLength)


{


int iEnd=0;


//接收端终止


if(pDlg->m_bRecEnd)


{


AfxMessageBox("接收端终止!");


goto ExitLable2;


}


//接收发送端状态数据


iNumByte=sockRecv.Receive(&iEnd, sizeof(int));


if(iNumByte == SOCKET_ERROR)


{


AfxMessageBox("接收信号错误!");


goto ExitLable2;


}


//发送端终止


if(iEnd==1)


{


AfxMessageBox("发送端终止!");


goto ExitLable2;


}




if((int)(uiLength - uiTotal) < iBufSize)


iSize = uiLength - uiTotal;


int iCount=0;


//读取定长数据


while(iCount<iSize)


{


iNumByte = sockRecv.Receive(pBuf, iSize-iCount);


if(iNumByte == SOCKET_ERROR)


{


AfxMessageBox("接收错误!");


goto ExitLable2;


}


iCount+=iNumByte;


file.Write(pBuf, iNumByte);


}


uiTotal += iCount;//以实际接收字节为准


//设置接收进度


pDlg->m_CtrlProgressRec.SetPos(int(((double)uiTotal/uiLength)*100));


str.Format("接收进度:%d%%",int(((double)uiTotal/uiLength)*100));


//显示接收进度百分比


pDlg->GetDlgItem(IDC_STATIC_REC)->GetWindowText(str1);


if(str1!=str)


pDlg->GetDlgItem(IDC_STATIC_REC)->SetWindowText(str);


}


//接收文件成功


AfxMessageBox("接收文件成功!");


bFileFail=TRUE;


ExitLable2:


delete[] pBuf;


file.Close();


//文件接收失败,则删除接收文件


if(!bFileFail)


{


Cfile::Remove( str2 );


}


sockRecv.Close();


pDlg->m_CtrlProgressRec.SetPos(0);//恢复接收进度


//禁止终止接收按钮


pDlg->GetDlgItem(IDC_BUTTON_REC_END)->EnableWindow(FALSE);


//打开接收按钮


pDlg->GetDlgItem(IDC_BUTTON_RECEIVE)->EnableWindow(TRUE);


//恢复提示进度


pDlg->GetDlgItem(IDC_STATIC_REC)->SetWindowText("接收进度:");


return 0;


}
zhy987916 2010-04-25
  • 打赏
  • 举报
回复
这个你要自己判断的,因为无论是TCP还是UDP的发送和接收方法都是序列化的接收和发送。参数是数组类型了,接收到的都是以字符串进行的。所以你应该自己判断。
文件传输嘛就要读文件,发送然后接收写文件和普通的发送接收差不多。唯一的区别是接收方要进行重组。
资料嘛呵呵直接Google就什么都有了

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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