本帖最后由 FlyHorsejun 于 2012-3-22 10:18 编辑
牺牲了一个周末的时间,做了一个局域网内的聊天小软件,可以进行文字聊天与图片传输。主要讲述一下在制作过程中遇到的一些问题以及一些技巧,希望对VC驿站的朋友们有所帮助,快了在于分享!!!O(∩_∩)O
对于文本的传输:基于UDP的网络传输协议。
对于图片的传输:基于TCP的网络传输协议。
这里大体介绍下两者的不同,TCP是面向连接的可靠的传输协议,UDP是无连接的不可靠的传输协议,想更了解的话,自行谷歌、百度吧! O(∩_∩)O
从上边的区别可以看的出来为什么选择不同的传输协议,传输图片之所以用TCP是因为图片都是以二进制数据的形式进行传输的,要保证传输的图片的质量,那自然是需要一个可靠的传输协议,否则,如果有数据丢失,接收到的图片质量肯定会受到影响,甚至不能形成完整的图片。而对于文本的传输,UDP的即时传输完全可以满足,虽然说UDP是不可靠的传输协议,但是UDP的优点是可以即时传输,不用像TCP一样每次连接都得需要进行三次握手,而且对于文字聊天来说,更重要的是即时性,至于偶尔丢失的那么点点的数据,几乎不会对聊天产生影响。
其实原来用的UDP协议,进行图片传输,本以为在局域网内进行传输应该不会有丢失情况,但是测试的时候情况出现了,传输的图片有的时候能够接收完整,有的时候接收部分,也就是不能显示出完整的图片,所以又改用TCP协议,经试验TCP协议可以避免丢失数据的现象。
程序大致思路:
程序将客户端和服务端放到了一块,也就是说程序即是客户端能够向服务端发送数据,又是服务端接收数据。
其中线程分为四个:主线程、接收文本信息的线程、接收图片信息的线程、发送图片信息的线程。至于发送文本信息,因为是UDP的本来就简单明了,感觉没有必要再为其创建线程。
socket套接字三个:一个为UDP的用于文本信息的收发,两个TCP的用于图片信息的收发。
用到的端口两个:6000和6666。
图片发送:建立连接后,发送端先将图片的名字和大小传递过去,然后再将图片文件以二进制的格式打开开始传送图片数据。接收端先接收图片的名字和大小,然后再创建文件将接收到的数据写入。
其下为我遇到的问题,感觉是些该注意的地方:
程序中用到了两个TCP的套接字,而只用了一个UDP的套接字:因为UDP是无连接的,所以用一个UDP的套接字就可以完成文本信息的发送和接收,TCP是面向连接的,发送和接收数据之前必须先建立连接,所以每个套机字只能完成一项功能。
发送较大的图片出现问题:原本是发送端发送完图片之后就直接关掉closesocket了,开始测试用的都是几十K的图片,改用了一个1M多的图片后发现出现错误,调试了很长时间才找出原来是发送端的closesocket太早,接收端还没有接收完就断开连接了,针对这个问题只需要在发送端发送完数据后再Sleep,让它小睡一会等接收端接收完数据再closesocket就OK啦!
其下为了解到得算是几个小技巧吧:
1. 得到应用程序的路径:
TCHAR TAppPath[20];
::GetModuleFileName(NULL,TAppPath,sizeof(TAppPath)/sizeof(TAppPath[0]));
(_tcsrchr(TAppPath, _T('\\')))[1] = 0;
_tcsrchr函数: 反向搜索获得最后一个TCHAR的位置
2. 设置CEdit控件的垂直滚动条到最下方:
int index=((CEdit*)GetDlgItem(IDE_SHOWMSG))->GetLineCount();
((CEdit*)GetDlgItem(IDE_SHOWMSG))->LineScroll(index,0);
3. 只运行一个应用程序:
1.通过命名互斥对象来实现。
HANDLE hMutex=CreateMutex(NULL,TRUE,"OneMutex");
if(hMutex)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
::AfxMessageBox(_T("已有程序在运行!"));
return FALSE;
}
}
2.通过事件对象来实现:
HANDLE hEvent=CreateEvent(NULL,FALSE,FALSE,"OneEvent");
if(hEvent)
{
if(GetLastError()==ERROR_ALREADY_EXISTS)
{
::AfxMessageBox(_T("已有程序在运行!"));
return FALSE;
}
}
如果想更了解的话还是请看源代码吧!我在程序中写了详细的注释,希望您能参阅指点。
注:我做过一个多小时的测试,程序有不足之处,因为发送有时候会有失败现象,但是绝大数的都能成功发送,我测试用的最大的图片是2.65M,能够成功传送,由于没有充分的时间去多做测试,所以程序中可能会有漏洞,望各位查看源代码给予指点,在下不胜感谢!
程序截图:
截图1.png (19.81 KB, 下载次数: 8)
2012-3-18 20:36 上传
截图2.png (29.49 KB, 下载次数: 1)
2012-3-18 20:36 上传
截图3.png (218.64 KB, 下载次数: 2)
2012-3-18 20:36 上传
源码下载:
游客,如果您要查看本帖隐藏内容请回复