socket聊天程序设计方案与实现.docx
《socket聊天程序设计方案与实现.docx》由会员分享,可在线阅读,更多相关《socket聊天程序设计方案与实现.docx(11页珍藏版)》请在冰点文库上搜索。
socket聊天程序设计方案与实现
封面
作者:
PanHongliang
仅供个人学习
基于socket的聊天程序设计与实现
学生姓名:
XXXXXXXX指导老师:
XXXXXXXXXXXX
摘要本设计在WINDOWS平台上,以C语言为编程语言,实现局域网内的即时通信工功能即聊天的功能。
本设计是基于WindowsSocket的编程,分别在同一局域网内的两台PC机的VC++6.0平台上运行服务端和客户端程序。
服务器与客户端在Windows7环境下采用了TCP/IP连接方式,由客户端登录到服务端PC机,实现客户端与服务端PC的信息传输。
关键词socket;C语言;TCP/IP;程序设计;VC++6.0
1引言
近年来,随着全球信息化进程的不断发展,网络也在飞速发展。
出于高效、快速地处理各种事务的目的,越来越多的企业在其内部使用局域网来进行工作。
在内部局域网的帮助下,企业得以简化信息流程,提高信息交换的速度,从而提高工作效率。
然而,随着企业规模的扩大,业务量的增加,在局域网上运行的应用越来越多,如知识库、网络会议、数据库应用和数据的同步与备份等,这些应用对局域网的信息吞吐、处理能力的要求也越来越高。
这些在企业内部原有局域网设计之初未曾考虑到的新情况的出现使得局域网不堪重负,容易发生信息阻塞,此时,局域网不但不能提高生产效率,反而成为企业发展的瓶颈。
为了解决上述矛盾,人们提出了许多方法。
提升网络带宽及增加服务器的吞吐能力是解决此矛盾的一种方法。
然而,从企业运行的成本方面考虑,无论是单纯地提升网络带宽或增加服务器的吞吐能力都不能从根本上解决局域网资源紧张的问题,对旧有局域网的大规模硬件改造反而会增加企业的负担。
基于Socket的局域网通信软件可以为企业原有的局域网提供一种良好,安全,快速的通信机制。
它的实现无需对企业原有的局域网硬件进行任何改动,具有实现成本低廉的优点,它的使用能有效地降低局域网通信负荷,提高局域网的使用效率,可以很好地解决企业内部局域网的各种通信需求。
基于Socket的局域网聊天工具是此类局域网通信软件的具体实例之一,它很好地诠释了Socket通信的原理,并且在企业内部通信、教案、讨论等应用中都具有一定的实用价值。
它具有信息收发速度快,保密性好,占用网络带宽资源低,占用服务器吞吐能力低,易于编程实现等优点。
基于Socket的局域网通信软件应用范围广阔,不但可以处理传统的通信需求,而且也能扩展以适应新型的网络应用,如网络教育,数据影音传输等,拥有广泛的应用前景。
1.1课程设计目的
了解基于socket的程序设计方法,增强程序编写能力,加深对计算机网络通信的理解。
另外,通过课程设计培养学生严谨的科学态度,认真的工作作风、团队协作精神、自主设计和独力思考的能力。
使同学们学会文献检索的基本方法和综合运用文献的能力。
1.2设计平台
网络:
局域网。
操作系统:
Windows7。
VC++6.0简介:
VC++6.0是Microsoft公司推出的一个基于Windows系统平台、可视化的集成开发环境,它的源程序按C++语言的要求编写,并加入了微软提供的功能强大的MFC(MicrosoftFoundationClass)类库。
MFC中封装了大部分WindowsAPI函数和Windows控件,它包含的功能涉及到整个Windows操作系统。
MFC不仅给用户提供了Windows图形环境下应用程序的框架,而且还提供了创建应用程序的组件,这样,开发人员不必从头设计创建和管理一个标准Windows应用程序所需的程序,而是从一个比较高的起点编程,故节省了大量的时间。
另外,它提供了大量的代码,指导用户编程时实现某些技术和功能。
因此,使用VC++提供的高度可视化的应用程序开发工具和MFC类库,可使应用程序开发变得简单。
2设计原理
程序采用WindowsSocket编程,利用MFC类库中,对WindowsSocketAPI进行了封装的CAsyncSocket类及其子类CSocket中提供的成员函数,完成网络的连接以及对字符消息的传送。
2.1win32编程原理
所谓的Win32开发,就是在C语言的层面上,直接使用Win32API开发Windows应用程序或者系统程序。
虽说现在直接用Win32API开发应用程序的人已经不多了,但是深入理解Windows系统程序设计原理,仍然是成为Windows开发高手的良好途径。
所谓的Win32,其实是一个API规范,与UNIX系统编程接口标准POSIX是相对应的。
下面是进行直接的WIN32SDK方式编程的基本思路或者说是一个框架:
一个WINDOWS程序分为程序代码和UI(UserInterface用户接口)资源两大部份,两部份最后以RC编译程序整合为一个完整的EXE文件。
所谓UI资源是指功能菜单、对话框、程序图标、光标形状等等东西。
这些UI资源的实际内容(二进制代码)系借助各种工具产生,并以各种扩展名存在,如.ico.bmp.cur等等。
程序员必须在一个所谓的资源描述档(.rc)中描述它们。
RC编译器(RC.EXE)读取RC文件的描述后将所有UI资源文件集中制作出一个.RES文件,再与程序代码结合在一起,这才是一个完整的Windows可执行文件。
与控制台程序相同的是,一个WIN32程序也必须有一个程序入口点,但是在这儿它不再叫main(),而叫做WinMain(),当WINDOWS的SHELL检测到用户欲执行一个EXE程序,就会调用加载器把程序进行加载,然后调用Cstartupcode,后者再调用WinMain(),程序的执行就开始了,WinMain()函数的原型为:
intCALLBACKWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow);
2.2TCP/IP协议简介
TCP/IP协议实际上就是在物理网上的一组完整的网络协议。
其中TCP是提供传输层服务,而IP则是提供网络层服务。
TCP/IP主要包括以下协议:
IP:
网间协议(InternetProtocol)负责主机间数据的路由和网络上数据的存储。
同时为ICMP,TCP,UDP提供分组发送服务。
用户进程通常不需要涉及这一层。
ICMP:
网间报文控制协议(InternetControlMessageProtocol)此协议处理网关和主机的差错和传送控制。
TCP:
传输控制协议(TransmissionControlProtocol)这是一种提供给用户进程的可靠的全双工字节流面向连接的协议。
它要为用户进程提供虚电路服务,并为数据可靠传输建立检查。
TCP/IP协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)和物
2.3WINDOWSSOCKETS网络编程接口概述
在网络编程中最常用的方案便是Client/Server(客户机/服务器)模型。
在这种方案中客户应用程序向服务器程序请求服务。
一个服务程序通常在一个众所周知的地址监听对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户向这个服务的地址提出了连接请求。
在这个时刻,服务程序被"惊醒"并且为客户提供服务-对客户的请求作出适当的反应。
为了方便这种Client/Server模型的网络编程,90年代初,由Microsoft联合了其他几家公司共同制定了一套WINDOWS下的网络编程接口,即WindowsSockets规范,它不是一种网络协议,而是一套开放的、支持多种协议的Windows下的网络编程接口。
现在的Winsock已经基本上实现了与协议无关,你可以使用Winsock来调用多种协议的功能,但较常使用的是TCP/IP协议。
Socket实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket接口的计算机通信。
应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。
微软为VisualC++定义了Winsock类如CAsyncSocket类和派生于CAsyncSocket的CSocket类,它们简单易用,我们当然可以使用这些类来实现自己的网络程序,但是为了更好的了解WinsockAPI编程技术,本设计中将使用底层的API函数实现Winsock平台的即时通信工具。
在VC中进行WINSOCK的API编程开发的时候,需要在工程中使用下面的三个文件,否则会出现编译错误。
(1)WINSOCK.H:
这是WINSOCKAPI的头文件,需要包含在工程中。
(2)WSOCK32.LIB:
WINSOCKAPI连接库文件。
(3)WINSOCK.DLL:
WINSOCK的动态连接库,位于WINDOWS的安装目录下。
3详细设计与实现
3.1客户端
连接模块设计:
客户端计算机获取本机开放的socket端口23,再发送目标主机的IP,通过connection()函数与服务端建立连接,如果connection()作用结果出现错误的socket,则连接失败,否则通过recv()函数接收服务器发送的字符串,即为服务器发送的欢迎信息。
模块程序如下:
……
intconnection()
{
WSAreturn=WSAStartup(0x101,&WSAData)。
//始化一个WSADATA结构
if(WSAreturn)
{
printf("发生一个未知错误!
\n")。
return0。
}
//创建一个套接口。
//第一个参数:
一个地址描述。
目前仅支持AF_INET格式,也就是说ARPAInternet地址格式。
//第二个参数:
新套接口的类型描述。
(SOCK_STREAM可用send()和recv()传送数据)
//第3个参数:
套接口所用的协议。
如调用者不想指定,可用0
client=socket(AF_INET,SOCK_STREAM,0)。
to.sin_family=AF_INET。
//sin_port存储端口号(使用网络字节顺序)
to.sin_port=htons(23)。
while(TRUE)
{
printf("请输入要登陆的IP:
")。
scanf("%s",&servername)。
//sin_addr存储IP地址,使用in_addr这个数据结构
to.sin_addr.s_addr=inet_addr(servername)。
printf("正在连接...\n")。
result=connect(client,(structsockaddr*)&to,sizeof(to))。
if(SOCKET_ERROR==result)
{
//连接失败
printf("对不起,无法连接到目标主机!
\n")。
WSACleanup()。
return0。
}
else
{
cansend=FALSE。
recv(client,receive,sizeof(receive),0)。
printf("*******欢迎消息消息*******\n")。
printf("%s\n",receive)。
printf("***********结束*********\n")。
……
信息发送与接收模块设计:
分别利用send()函数和recv()函数发送和接收信息。
模块程序如下:
……
scanf("%s\0",&chatto)。
send(client,chatto,strlen(chatto),0)。
……
recv(client,chatfrom,sizeof(chatfrom),0)。
printf("%s\n",chatfrom)。
3.2服务端
连接用户模块设计:
通过GetIp()函数获得客户端IP,然后开放一个端口,绑定并监听端口。
接受来自客户端的连接,并向客户端发送欢迎信息。
与客户端建立连接。
模块程序如下:
……
intGetIp()
{
WSAreturn=WSAStartup(0x101,&WSAData)。
if(WSAreturn)
{
printf("发生一个未知错误!
\n")。
return0。
}
local.sin_family=AF_INET。
local.sin_addr.s_addr=INADDR_ANY。
local.sin_port=htons((u_short)23)。
server=socket(AF_INET,SOCK_STREAM,0)。
if(server==INVALID_SOCKET)
{
printf("无法创建套接字!
\n")。
return0。
}
if(bind(server,(structsockaddr*)&local,sizeof(local))!
=0)
{
printf("无法绑定套接字!
\n")。
return0。
}
if(listen(server,5)!
=0)
{
printf("无法监听端口!
\n")。
return0。
}
while(TRUE)
{
printf("正在等待用户连接...\n")。
client=accept(server,(structsockaddr*)&from,&fromlen)。
strcpy(information,inet_ntoa(from.sin_addr))。
strcat(welcome,information)。
printf("接受来自%s的连接...\n",inet_ntoa(from.sin_addr))。
printf("正在发送欢迎消息...\n")。
send(client,welcome,strlen(welcome),0)。
//send(client,ip,strlen(ip),0)。
//send(client,information,strlen(information),0)。
printf("欢迎消息信息已经成功发送至客户端!
\n")。
……
信息发送与接收模块设计:
分别利用send()函数和recv()函数发送和接收信息。
模块程序如下:
……
recv(client,receive,sizeof(receive),0)。
printf("%s\n",receive)。
……
scanf("%s\0",&chat)。
send(client,chat,strlen(chat),0)。
……
4运行结果
在局域网内的一台PC机的VC++6.0平台上运行服务端程序,并与客户端PC机之间通信。
程序运行窗口如下图所示:
图4.1服务端程序运行后的聊天窗口
在同一局域网内的另一台PC机的VC++6.0平台上运行服务端程序,并与客户端PC机之间进行通信。
程序运行窗口如下图所示:
图4.2客户端程序运行后的聊天窗口
5出现问题及解决方法
在编写服务端和客户端程序时,始终出现链接错误。
错误提示如:
errorLNK2001:
unresolvedexternalsymbol__imp__closesocket@4。
…
Debug/00.exe:
fatalerrorLNK1120:
9unresolvedexternals
Errorexecutinglink.exe.
其问题在于缺少一句连接到库的语句。
因此,其解决办法是在程序开头添加一条连接到库的语句即可。
6结束语
两个星期的时间很快就过去了,计算机网络课程设计也即将结束.在这两个星期里,有过不少的艰辛和疑惑,我从刚开始的无从下手到最后的顺利完成,我又一次体验了自我设计的满足感.
课程设计刚开始,当老师把题目布下来的时候,我疑惑了许久,在此之前我很少接触基于socket的程序设计,因而对于这个题目我感到无从下手,但是通过老师的指导和本人上网查阅资料后,我对基于socket的程序设计有了大概的了解.但与此同时另一个问题也正困扰着我,那就是我该先择什么语言设计这个聊天程序来实现聊天功能呢.据指导老师介绍,对基于socket的设计,任意的编程语言可以适用.由于通信专业所学编程语言比较少,再加上本人对C和C++语言编程了解的要多一些.因此,尽管用C语言编起来比较繁琐,但是我还是先择了C语言。
选择设计语言后,稍微复习了C语言的一些知识,尽管这样,但我还是没有比较清楚的设计思.因此,我还不断地查阅资料,学习别人的设计思路和方法,然后结合自己的想法将程序不断地完善.这样我的设计工作得以顺利地进行。
设计完成后,还有一个重要的工作就是论文的编写.由于在此之前我们已经完成过若干个课程设计论文,因此我对论文的编写也有了较丰富的经验,在排版和格式方面都已经相当熟悉,所有论文的编写也是完成得比较的顺利.
在这两个星期的课程设计中,与其说是完成设计,我更觉得这是一个学习的过程。
在设计过程中,我有很多的知识不懂或者已经淡忘了,但是通过求教于老师和同学,并勤于查阅资料,我又学到了很多的知识。
本人真切地感受到此次课程设计带给我的学习动力与兴趣.我相信有了这些,将会对我以后的专业知识学习更加有利.
此次课程设计的顺利完成,还归功于老师殷切的指导和无私的帮助。
在此,我向老师们表示衷心地感谢!
参考文献
[1]杨路明.C语言程序设计.北京:
北京邮电大学出版社,2005
[2]谢希仁.计算机网络.北京:
电子工业出版社,2008
版权申明
本文部分内容,包括文字、图片、以及设计等在网上搜集整理。
版权为潘宏亮个人所有
Thisarticleincludessomeparts,includingtext,pictures,anddesign.CopyrightisPanHongliang'spersonalownership.
用户可将本文的内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。
除此以外,将本文任何内容或服务用于其他用途时,须征得本人及相关权利人的书面许可,并支付报酬。
Usersmayusethecontentsorservicesofthisarticleforpersonalstudy,researchorappreciation,andothernon-commercialornon-profitpurposes,butatthesametime,theyshallabidebytheprovisionsofcopyrightlawandotherrelevantlaws,andshallnotinfringeuponthelegitimaterightsofthiswebsiteanditsrelevantobligees.Inaddition,whenanycontentorserviceofthisarticleisusedforotherpurposes,writtenpermissionandremunerationshallbeobtainedfromthepersonconcernedandtherelevantobligee.