基于TCP的简单一对一聊天程序设计_第1页
基于TCP的简单一对一聊天程序设计_第2页
基于TCP的简单一对一聊天程序设计_第3页
基于TCP的简单一对一聊天程序设计_第4页
基于TCP的简单一对一聊天程序设计_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、课程设计题目:通过套接字连接进行一对一聊天通信二、实验要求:实现一个一对一的聊天程序。根本过程如下:效劳器首先启动,创立套接字后等待客户的连接;客户启动以后,创立套接字,然后和效劳器建立连接;连接建立后,客户机和效劳器可以通过建立的套接字连接进行通信。效劳器和客户端可以是一台电脑的两个进程,也可以分别部署在两台电脑上。三、原理概述:套接字Socket是一种双向的通信接口,可以通过这个端口与任何一个具有Socket端口的计算机通信,套接字是网络通信的根底。Socket在Windows以句柄的形式被创立。使用Socket进行网络通信必须包含下面的几种信息:双方认可的协议,本地主机的IP地址,本地进程的协议端口,对方主机的IP地址,对方进程的协议端口。Socket可分为:1数据报套接字〔DatagramSockets〕——对于在TCP/IP上实现的WinSock,数据报套接字使用用户数据报协议〔UDP〕。数据报套接字提供了一种不可靠的、非连接的数据包通信方式。2流式套接字〔StreamSockets〕——流式套接字使用传输控制协议〔TCP〕。流式套接字可以将数据按顺序无重复地发送到目的地,它提供的是一种可靠的、面向连接的数据传输方式。不管是对单个的数据报,还是对数据包,流式套接字都提供了一种流式数据传输。VC++对网络编程的支持有socket支持,Winlnet支持,MAPI和ISAPI支持等。其中WindowsSocketsAPI是TCP/IP网络环境里,也是Internet上进行开发最为通用的API。IP地址:IPAddress就是依照TCP/IP协议分配给本地主机的网络地址,就向两个进程要通讯,任一进程要知道通讯对方的位置,位置如何来确定,就用对方的IP端口号:用来标识本地通讯进程,方便OS提交数据.就是说进程指定了对方进程的网络IP,但这个IP只是用来标识进程所在的主机,如何来找到运行在这个主机的这个进程呢,就用端口号.连接:指两个进程间的通讯链路.一个完整的网间进程通信需要由两个进程组成,并且只能使用同一种高层协议。也就是说,不可能通信的一端用TCP协议,而另一端用UDP协议。因此一个完整的网间通信需要一个五元组来标识:协议,本地地址,本地端口号,远地地址,远地端口号这样一个五元组,叫做一个相关association,即两个协议相同的半相关才能组合成一个适宜的相关,或完全指定组成一连接。在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户/效劳器模式(Client/Servermodel),即客户向效劳器发出效劳请求,效劳器接收到请求后,提供相应的效劳。客户/效劳器模式的建立基于以下两点:首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供效劳,资源较少的客户请求效劳这一非对等作用。其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步,这就是基涌纪纪户/效劳器模式的TCP/IP。四.设计方案:设计原理图:解决方案基于TCP连接Socket聊天程序基于该连接的聊天程序需要至少具备一个效劳器端〔Server〕和一个客户端〔Client〕。在本程序中,一个用户作为Server端,另一个用户作为Client端。也就是说,作为Server端的用户,需要首先启动程序,等待Client端的连接请求。当TCP连接握手以后,双方方可进行交互。在本程序中Server端并不是单独存在。它也可以向他的Client端发送消息。当Client端与Server端握手以后,Server端需要首先发起会话;Client端在收到消息后再回复一条消息给Server端;同样,Server端在收到消息后再回复一条消息给Client端……以此类推。五.程序编写:Server.h代码如下:#include<Afxwin.h>#include<stdio.h>#include<winsock2.h>#include<conio.h>#include<list>#include<iostream>usingnamespacestd;classCChatServer{public: CChatServer(); ~CChatServer(); boolIsConnected(){returnm_bIsConnected;}//返回连接状态 voidStartListenClient();//Listentoclient intSendMessagePort(stringsMessage);//向所有客户端发消息 intRecClient(SOCKETsRecSocket);//接收客户端数据private: boolm_bIsConnected;//true-connectedfalse-notconnected intm_iServerPort; list<SOCKET>m_vClientList;//Allsocketconnectedtoclient SOCKETm_SClient; SOCKETm_SListenClient;//socketlisteningforclientcalls};Server.cpp代码如下:#include"server.h"CChatServerCServerObj;UINTServerRecThread(LPVOIDpParam)//接收数据的工作线程{ SOCKETsRecSocket=(SOCKET)pParam; while(1) { if(CServerObj.RecClient(sRecSocket)) break; } return0;}UINTServerListenThread(LPVOIDpParam)//监听端口建立连接的工作线程{ while(1) CServerObj.StartListenClient(); return0;}CChatServer::CChatServer()//对象CChatServer的构造函数{cout<<"StartingupTCPChatserver\n"; m_bIsConnected=false;WSADATAwsaData;sockaddr_inlocal;intwsaret=WSAStartup(0x101,&wsaData);//应用程序调用的第一个WindowsSockets函数.//它允许应用程序或DLL指明WindowsSocketsAPI的版本号及获得特定WindowsSockets实现的细节.if(wsaret!=0){return;}local.sin_family=AF_INET;local.sin_addr.s_addr=INADDR_ANY;local.sin_port=htons((u_short)8084);m_SListenClient=socket(AF_INET,SOCK_STREAM,0);//创立一个套接字,返回套接字描述字if(m_SListenClient==INVALID_SOCKET){return;}if(bind(m_SListenClient,(sockaddr*)&local,sizeof(local))!=0)//把本地协议的地址赋予一个套接字{return;}if(listen(m_SListenClient,10)!=0)//监听该端口{return;} m_bIsConnected=true;return;}CChatServer::~CChatServer()//对象CChatServer的析构函数{closesocket(m_SListenClient);//关闭该端口WSACleanup();}voidCChatServer::StartListenClient(){sockaddr_infrom;intfromlen=sizeof(from);m_SClient=accept(m_SListenClient,(structsockaddr*)&from,&fromlen);//产生与客户进行TCP连接通信的套接字并返回已连接客户端的协议地址 if(m_SClient!=INVALID_SOCKET) m_vClientList.push_back(m_SClient); AfxBeginThread(ServerRecThread,(void*)m_SClient);//启动接收线程,用m_SClient套接字与客户端通话}intCChatServer::SendMessagePort(stringsMessage)//向各个客户端发送效劳器数据{ intiStat=0; list<SOCKET>::iteratoritl; if(m_vClientList.size()==0) return0; for(itl=m_vClientList.begin();itl!=m_vClientList.end();itl++) { iStat=send(*itl,sMessage.c_str(),sMessage.size()+1,0); if(iStat==-1) m_vClientList.remove(*itl); } if(iStat==-1) return1; return0;}intCChatServer::RecClient(SOCKETsRecSocket)//接收客户端数据成员函数{chartemp[4096]; intiStat; iStat=recv(sRecSocket,temp,4096,0); if(iStat==-1) { m_vClientList.remove(sRecSocket); return1; } else { cout<<":"<<temp<<"\n"; SendMessagePort(temp); return0; } return0;}intmain(intargc,char*argv[]){intnRetCode=0; charbuf[4096]; cout<<"Thisaplicationactasachatserver.\n"; cout<<"Messagesfromanypcwillbebroadcastedtoallconnectedpcs.\n"; cout<<"Connecttotheserverpcport8084\n";cout<<"PressONLYENTERtoquit.\n"; cout<<"=================================================\n"; if(!CServerObj.IsConnected())//判断监听端口是否建立 { cout<<"\nFailedtoinitialiseserversocket"; cout<<"\nBye"; getch(); return1; } AfxBeginThread(ServerListenThread,0);//启动监听端口建立连接的工作线程 while(gets(buf)) { if(strlen(buf)==0) break; if(CServerObj.SendMessagePort(buf)) { cout<<"Probleminconnectingtoserver.Checkwhetherserverisrunning\n"; break; } } cout<<"readytoseegoodbye:"; getch();returnnRetCode;}Client.h#include<Afxwin.h>#include<stdio.h>#include<winsock2.h>#include<conio.h>#include<iostream>usingnamespacestd;classCIPMessage{public: CIPMessage(); ~CIPMessage(); voidInit(stringsIpAddress,intiPort); intSendMessagePort(stringsMessage); intRecMessagePort(); boolIsConnected(){returnm_bIsConnected;}private: boolm_bIsConnected;//true-connectedfalse-notconnected stringm_sServerIPAddress; intm_iServerPort; SOCKETconn;//socketconnectedtoserver};Client.cpp代码如下:#include"client.h"//GlobalMessageobjectCIPMessageMyMessObj;CIPMessage::CIPMessage()//MyMessObj构造函数{ m_bIsConnected=false;}voidCIPMessage::Init(stringsIpAddress,intiPort)//建立与效劳器端得连接{ m_sServerIPAddress=sIpAddress; m_iServerPort=iPort; structhostent*hp; unsignedintaddr; structsockaddr_inserver; WSADATAwsaData; intwsaret=WSAStartup(0x101,&wsaData);//应用程序调用的第一个WindowsSockets函数.//它允许应用程序或DLL指明WindowsSocketsAPI的版本号及获得特定WindowsSockets实现的细节. if(wsaret!=0) { return; } conn=socket(AF_INET,SOCK_STREAM,0);//建立客户端套接字 if(conn==INVALID_SOCKET) return; addr=inet_addr(m_sServerIPAddress.c_str());//转化ip地址和端口为指定形式 hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET); if(hp==NULL) { closesocket(conn); return; } server.sin_addr.s_addr=*((unsignedlong*)hp->h_addr); server.sin_family=AF_INET; server.sin_port=htons(m_iServerPort); if(connect(conn,(structsockaddr*)&server,sizeof(server)))//向指定效劳器建立连接 { closesocket(conn); return; } m_bIsConnected=true; return;}CIPMessage::~CIPMessage()//MyMessObj析构函数{ if(m_bIsConnected) closesocket(conn);}intCIPMessage::SendMessagePort(stringsMessage)//向指定效劳器发出数据{ intiStat=0; iStat=send(conn,sMessage.c_str(),sMessage.size()+1,0); if(iStat==-1) return1; return0;}intCIPMessage::RecMessagePort()//接收指定效劳器数据{ characRetData[4096]; intiStat=0; iStat=recv(conn,acRetData,4096,0); if(iStat==-1) return1; cout<<"-->:"<<acRetData<<"\n"; return0;}UINTMessageRecThread(LPVOIDpParam)//接收指定效劳器数据线程{ while(1) { if(MyMessObj.RecMessagePort()) break; } return0;}intmain(intargc,char*argv[]){ charbuf[4096]; cout<<"ThisisaclientTCP/IPapplication\nConnectingtoport8084\n"; cout<<"\nPressONLYENTERtoquit"; cout<<"\n===============================================\n"; FILE*fp=fopen("server.ini","r");//获取效劳器端套接字地址 if(fp==NULL) { cout<<"\nUnabletoopenserver.ini.PleasespecifyserverIPsddressinserver.ini"; return1;//mainfailed } stringsServerAddress; while((fgets(buf,4096,fp))!=NULL) { if(buf[0]=='#') continue; sServerAddress=buf; } fclose(fp); if(sServerAddress.size()==0) { cout<<"\nUnabletofindserverIPaddressinserver.ini"; cout<<"\nPleasesetserverIPaddress"; cout<<"\nBYEBYE:"; getch(); return0; } MyMessObj.Init(sServerAddress.c_str(),8084);//启动与效劳器连接 if(!MyMessObj.IsConnected()) { cout<<"\nUnabletoconnecttotheIPaddressspecifiedinserver.ini"; cout<<"\nPleasecheckserverIPaddress"; cout<<"\nreadytoseegoodbye:"; getch(); return0; } AfxBeginThread(MessageRecThread,0);//开启接收数据线程 while(ge

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论