北邮程序设计实践报告(聊天程序)附源代码
程序设计实践
课题名称:聊天程序
学生姓名:
班 级:
班内序号:
学 号:
日 期: 设 计 报 告 2014/6/6
1. 课题概述
1.1课题目标和主要内容
聊天程序虽然形态各异,但就其本质,却是相同的。这种程序一般由两大部分组成:服务器端聊天程序和客户端聊天程序。服务器端聊天程序负责接收来自客户端的聊天信息,并且根据客户端的要求把这些信息转发到另外一个活多个客户中。客户端聊天程序则负责建立与维护与服务器端的连接,向服务器发送本客户的聊天内容,同时从服务器接收对方的响应。
1.2系统的主要功能
(1)可以手动输入服务器IP地址和端口号进行连接(客户端功能)。
(2)可以手动建立服务器接受其他客户端的连接要求(服务端功能)。
(3)可以发送消息给服务端,显示服务端传来消息(客户端功能)。
(4)可以接收客户端发送的消息,并将消息传给所有在线的客户端(服务端功能)。
2. 系统设计
2.1 系统总体框架
2.2 系统详细设计
服务端:
[1] 模块划分图及描述
(1)在特定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连
接表,以记录所有成功的连接。
(2)及时接收各个聊天客户发送过来的信息,然后把这些信息转发到一个或多个客户连接。
(3)监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应的表项,并及时更新连接表。
[2] 类关系图及描述
CServerSocket类的主要功能是实现OnAccept()消息,负责监听服务端口,是一个服务Socket。此类头文件代码如下:
// CServerSocket command target
class CChatDlg;
class CServerSocket : public CSocket
{
// Attributes
public:
CChatDlg * m_dlg;
UINT m_uPort;
BOOL Init(UINT port, CChatDlg* dlg);
// Operations
public:
CServerSocket(){};
virtual ~CServerSocket(){};
// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerSocket)
//使用类向导添加的
public:
virtual void OnAccept(int nErrorCode);
//}}AFX_VIRTUAL
// Generated message map functions
//{{AFX_MSG(CServerSocket)
// Implementation
protected:
};
/////////////////////////////////////////////////////////////////////////////
// NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif
// !defined(AFX_SERVERSOCKET_H__03952A19_3B2C_45BD_B9BB_FBBD072ED603__INCLUDED_)
[3] 存储结构、内存分配
此模块用到了列表的存储结构
客户端:
[1] 模块划分图及描述
(1)建立和维护与服务器的连接,并且随时监测连接的状态。
(2)把用户输入的信息及时发送到服务端,同时,随时准备好接收服务端的信息,并将它显示出来。
(3)在用户退出聊天过程时要关闭与服务端的连接。
[2] 类关系图及描述
CClientSocket类通过相应的OnReceive消息来接受数据,响应OnClose消息来断开对话的处理。CClientSocket类实现了以CArchive对数据进行的串行化。本类的头文件源代码如下:
#include "PackMessg.h"
///////////////////////////////////////////////////////////////////////////// // CClientSocket command target
class CChatDlg;
class CClientSocket : public CSocket
{
// Attributes
public:
CArchive* m_aSessionIn;
CArchive* m_aSessionOut;
CSocketFile* m_sfSocketFile;
CChatDlg * m_dlg;
bool m_bInit; //作为套接字是否被初始化的标记
bool m_bClose; //作为套接字是否被关闭的标记
// Operations
public:
void Init(CChatDlg * dlg);
BOOL SendMessage(CPackMessg * msg);
void CloseSocket();
public:
static int GetLocalHostName(CString &sHostName);
地IP
static int GetIpAddress(const CString &sHostName, BYTE &f0,BYTE &f1,BYTE &f2,BYTE &f3);//获得本地IP
static CString ErrorReason(int tag);
public:
CClientSocket();
virtual ~CClientSocket();
// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CClientSocket)
//通过classwizard添加到类中的成员函数
public:
virtual void OnReceive(int nErrorCode);
virtual void OnClose(int nErrorCode);
//}}AFX_VIRTUAL
// Generated message map functions
//{{AFX_MSG(CClientSocket)
// Implementation
protected:
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG //获得本地计算机名称 static int GetIpAddress(const CString &sHostName, CString &sIpAddress);//获得本
bool m_bClose; //作为套接字是否被关闭的标记 // Operations public:
void Init(CChatDlg * dlg);
BOOL SendMessage(CPackMessg * msg); void CloseSocket(); public:
static int GetLocalHostName(CString &sHostName); 地IP
static int GetIpAddress(const CString &sHostName, BYTE &f0,BYTE &f1,BYTE &f2,BYTE &f3);//获得本地IP
static CString ErrorReason(int tag); public:
CClientSocket();
virtual ~CClientSocket();
// Overrides public:
// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CClientSocket)
//通过classwizard添加到类中的成员函数
public:
virtual void OnReceive(int nErrorCode); virtual void OnClose(int nErrorCode); //}}AFX_VIRTUAL
// Generated message map functions //{{AFX_MSG(CClientSocket)
// Implementation protected: };
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
//获得本地计算机名称
static int GetIpAddress(const CString &sHostName, CString &sIpAddress);//获得本
previous line. #endif
// !defined(AFX_CLIENTSOCKET_H__9A3B7A03_0D59_4A60_ABA2_35D6CA850937__INCLUDED_)
否
2.3 关键算法分析
算法1:CServerSocket::Init [1] 算法功能
初始化服务端
[2] 算法基本思想
服务端建立套接字,并且进入监听状态。
[3] 算法空间、时间复杂度分析
O(1)
[4] 代码逻辑(可用伪代码描述)
BOOL CServerSocket::Init(UINT port, CChatDlg* dlg) {
m_uPort=port; m_dlg=dlg;
if(Create(m_uPort)==FALSE) { }
if(this->Listen()==FALSE) { }
m_dlg->SetDlgItemText(IDC_SHOWMESSAGE,"服务器创建成功!"); return TRUE; }
AfxMessageBox("服务器监听错误!"); return FALSE;
AfxMessageBox("服务器套接字创建失败!"); return FALSE;
算法2:CClientSocket::OnReceive
[1] 算法功能 接收数据
[2] 算法基本思想
如果为客户端,将此响应传递到所有与此连接的客户端,如果为客户端,接收响应。
[3] 算法空间、时间复杂度分析
O(n)、O(1)
[4] 代码逻辑(可用伪代码描述)
void CClientSocket::OnReceive(int nErrorCode) {
// TODO: Add your specialized code here and/or call the base class
CSocket::OnReceive(nErrorCode); do { }
while (!m_aSessionIn->IsBufferEmpty()); }
CPackMessg temp;
temp.Serialize(*m_aSessionIn);
m_dlg->m_sMsgList+=temp.m_strText+"\r\n";
m_dlg->SetDlgItemText(IDC_SHOWMESSAGE,m_dlg->m_sMsgList); int linenum=((CEdit
((CEdit *)(m_dlg->GetDlgItem(IDC_SHOWMESSAGE)))->LineScroll(linenum); if(!m_dlg->m_bClient) { }
for(POSITION { }
CClientSocket * t =
if(t->m_hSocket!=this->m_hSocket) { }
t->SendMessage(&temp);
*)(m_dlg->GetDlgItem(IDC_SHOWMESSAGE)))->GetLineCount();
pos=m_dlg->m_connectionList.GetHeadPosition();pos!=NULL;)
(CClientSocket*)m_dlg->m_connectionList.GetNext(pos);
算法3:CClientSocket::SendMessage [1] 算法功能
发送消息
[2] 算法基本思想
检查连接情况,若断开,关闭对话,若连接,发送消息。
[3] 算法空间、时间复杂度分析
O(1)
[4] 代码逻辑(可用伪代码描述)
BOOL CClientSocket::SendMessage(CPackMessg * msg) {
if (m_aSessionOut != NULL) { } else { } }
//对方关闭了连接 m_bClose=true; CloseSocket();
m_dlg->CloseSessionSocket(); return FALSE;
msg->Serialize(*m_aSessionOut); m_aSessionOut->Flush(); return TRUE;
3. 程序运行结果分析
4. 总结
4.1课题的难点和关键点
本课题的关键点在于对Sockets的理解和运用。Sockets是Windows下网络
编程的规范,Windows Sockets是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。 本课题采用的是客户机/服务器模型,此模型工作时要求有一套为客户机和服务器所共识的惯例来保证服务能够被提供(或被接受)。这一套惯例包含了一套协议。它必须在通讯的两头都被实现。根据不同的实际情况,协议可能是对称的或是非对称的。在对称的协议中,每一方都有可能扮演主从角色;在非对称协议中,一方被不可改变地认为是主机,而另一方则是从机。一个对称协议的例子是Internet中用于终端仿真的TELNET。而非对称协议的例子是Internet中的FTP。无论具体的协议是对称的或是非对称的,当服务被提供时必然存在"客户进程"和"服务进程"。一个服务程序通常在一个众所周知的地址监听对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户对这个服务的地址提出了连接请求。在这个时刻,服务程序被"惊醒"并且为客户提供服务-对客户的请求作出适当的反应。这一请求/相应的过程可以简单的用图表示。虽然基于连接的服务是设计客户机/服务器应用程序时的标准,但有些服务也是可以通过数据报套接口提供的。
4.2 本课题的评价
本课题在之前的MFC编程的基础上,加入了对于网络技术应用的结合,让我
们更深刻得了解了MFC编程的灵活性和实用性。
另外,本次设计的软件只能进行基本的文本通信,确实有很多的遗憾。我觉
得还可以改进和添加的功能有:
a) 可以把聊天记录用一个独立的窗口进行显示
b) 界面美工和排版
c) 可以传输文件
d) 可以进行语音或视频聊天
4.3心得体会
大一我们接触了C++的编程,主要以面向过程为主。这学期的实践课让我们
更多得接触了面向对象的编程,并主要学习了MFC的编程过程。而这一课题在上一课题的基础上,又有一定的提高。事实上,在实用中,MFC编程常常和网络协议,数据库等结合使用,如本课题就用到了套接字的原理。而通过本课题的学习与练习,让我们对这种综合性的编程有了初步的接触,也为今后的学习开了头。
5. 参考文献
[1]Visual C++课程设计案例精编/夏崇普,任海军,余健编著——北京:清华大学出版社,2008.11
源代码:
// chatDlg.cpp : implementation file
//
#include "stdafx.h"
#include "chat.h"
#include "chatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
// Dialog Data
// Implementation
protected:
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT
//{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA CAboutDlg();
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
///////////////////////////////////////////////////////////////////////////// // CChatDlg dialog
CChatDlg::CChatDlg(CWnd* pParent /*=NULL*/)
{
}
void CChatDlg::DoDataExchange(CDataExchange* pDX)
{
}
BEGIN_MESSAGE_MAP(CChatDlg, CDialog)
//{{AFX_MSG_MAP(CChatDlg) CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CChatDlg) DDX_Text(pDX, IDC_MESSAGE, m_strMessage); DDX_Text(pDX, IDC_NAME, m_strName); DDX_Text(pDX, IDC_PORT, m_port); DDX_Text(pDX, IDC_SHOWMESSAGE, m_strShowMessage); //}}AFX_DATA_MAP //{{AFX_DATA_INIT(CChatDlg) m_strMessage = _T(""); m_strName = _T(""); m_port =5000; m_strShowMessage = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); : CDialog(CChatDlg::IDD, pParent) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CChatDlg message handlers
BOOL CChatDlg::OnInitDialog()
{
// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE); // TODO: Add extra initialization here //自行添加的程序代码,目的是在初始化对话框的时候就自动显示出本地的ip地址 if(AfxSocketInit(NULL)==0) { AfxMessageBox("CSocket 初始化失败!"); // Set big icon // Set small icon CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { } CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { } pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX
}
void CChatDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
}
// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.
void CChatDlg::OnPaint()
{
// Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); if (IsIconic()) { CPaintDC dc(this); // device context for painting if ((nID & 0xFFF0) == IDM_ABOUTBOX) { } else { } CDialog::OnSysCommand(nID, lParam); CAboutDlg dlgAbout; dlgAbout.DoModal(); BYTE f0,f1,f2,f3; CString name; CClientSocket::GetLocalHostName(name); CClientSocket::GetIpAddress(name,f0,f1,f2,f3); ((CIPAddressCtrl *)(GetDlgItem(IDC_IPADDRESS)))->SetAddress(f0,f1,f2,f3); m_bInit=false; m_bClient=false; return TRUE; // return TRUE unless you set the focus to a control
}
// The system calls this to obtain the cursor to display while the user drags // the minimized window.
HCURSOR CChatDlg::OnQueryDragIcon()
{
}
//连接服务器的消息相应函数
void CChatDlg::OnConnect()
{
}
//建立服务器的消息相应函数 // TODO: Add your control notification handler code here if(!m_bInit) { } BYTE f0,f1,f2,f3; CString name; ((CIPAddressCtrl *)(GetDlgItem(IDC_IPADDRESS)))->GetAddress(f0,f1,f2,f3); CString ip; ip.Format("%d.%d.%d.%d",f0,f1,f2,f3); m_bClient=true; m_clientsocket.Create(); if(m_clientsocket.Connect(ip,GetDlgItemInt(IDC_PORT))) { } else { } m_clientsocket.Close(); AfxMessageBox("客户端连接失败!"); m_bInit=false; m_clientsocket.Init(this); SetDlgItemText(IDC_SHOWMESSAGE,"客户端连接成功!"); m_bInit=true; return (HCURSOR) m_hIcon; } else { } CDialog::OnPaint(); // Draw the icon dc.DrawIcon(x, y, m_hIcon);
void CChatDlg::OnSetserver() {
}
//发送消息的按钮的消息相应函数 void CChatDlg::OnSend()
{
if(in.GetLength()>2) { m_sMsgList+=m_strName+"说:"; m_sMsgList+=in+"\r\n"; SetDlgItemText(IDC_SHOWMESSAGE,m_sMsgList); int m_iLineCurrentPos=((CEdit *)(GetDlgItem(IDC_SHOWMESSAGE)))->GetLineCount(); ((CEdit *)(GetDlgItem(IDC_SHOWMESSAGE)))->LineScroll(m_iLineCurrentPos); msg.m_strText=m_strName+"说:"+in; if(!m_bClient) // TODO: Add your control notification handler code here if(!m_bInit) { } CString in; CPackMessg msg; GetDlgItemText(IDC_MESSAGE,in); GetDlgItemText(IDC_NAME,m_strName); if(in.GetLength()
}
void CChatDlg::ProcessPendingAccept() {
}
void CChatDlg::ClearContent() {
if(m_bClient) { m_clientsocket.Close(); } else delete pSocket; POSITION pos; for(pos=m_connectionList.GetHeadPosition();pos!=NULL;) { } pSocket->Init(this); m_connectionList.AddTail(pSocket); CClientSocket * t= (CClientSocket *)m_connectionList.GetNext(pos); t->SendMessage(&msg); CClientSocket* pSocket = new CClientSocket(); if (m_pListenSocket.Accept(*pSocket)) { CPackMessg msg; msg.m_strText="一个游客进入聊天室了"; SetDlgItemText(IDC_SHOWMESSAGE,"一个游客进入聊天室了\n"); } { } else { } m_clientsocket.SendMessage(&msg); POSITION pos; for(pos=m_connectionList.GetHeadPosition();pos!=NULL;) { } CClientSocket * t= (CClientSocket *)m_connectionList.GetNext(pos); t->SendMessage(&msg); // m_strShowMessage+="一个游客进入聊天室了\n";
}
void CChatDlg::OnClearconnection()
{
}
void CChatDlg::CloseSessionSocket()
{
} if(!m_bClient) { } for(POSITION pos=m_connectionList.GetHeadPosition();pos!=NULL;) { } POSITION t_pos=pos; CClientSocket * t = (CClientSocket*)m_connectionList.GetNext(pos); if(t->m_bClose==true) { } m_connectionList.RemoveAt(t_pos); ClearContent(); } else { } m_bInit=false; m_sMsgList=""; SetDlgItemText(IDC_MESSAGE,""); SetDlgItemText(IDC_SHOWMESSAGE,""); m_pListenSocket.Close(); m_connectionList.RemoveAll();
// ClientSocket.cpp : implementation file
//
#include "stdafx.h"
#include "chat.h"
#include "ClientSocket.h"
#include "chatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CClientSocket
CClientSocket::CClientSocket()
{
}
CClientSocket::~CClientSocket()
{
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CClientSocket, CSocket)
//{{AFX_MSG_MAP(CClientSocket) //}}AFX_MSG_MAP
// 0 if(m_aSessionIn) delete m_aSessionIn; delete m_aSessionOut; delete m_sfSocketFile; if(m_aSessionOut) if(m_sfSocketFile) m_aSessionIn=NULL; m_aSessionOut=NULL; m_sfSocketFile=NULL; m_bInit=false; m_bClose=false; END_MESSAGE_MAP() #endif
/////////////////////////////////////////////////////////////////////////////
// CClientSocket member functions
void CClientSocket::OnReceive(int nErrorCode)
{
}
void CClientSocket::OnClose(int nErrorCode)
{
}
void CClientSocket::Init(CChatDlg * dlg) // TODO: Add your specialized code here and/or call the base class CSocket::OnClose(nErrorCode); m_bClose=true; CloseSocket(); m_dlg->CloseSessionSocket(); CSocket::OnClose(nErrorCode); // TODO: Add your specialized code here and/or call the base class CSocket::OnReceive(nErrorCode); do { } while (!m_aSessionIn->IsBufferEmpty()); CPackMessg temp; temp.Serialize(*m_aSessionIn); m_dlg->m_sMsgList+=temp.m_strText+"\r\n"; m_dlg->SetDlgItemText(IDC_SHOWMESSAGE,m_dlg->m_sMsgList); int linenum=((CEdit *)(m_dlg->GetDlgItem(IDC_SHOWMESSAGE)))->GetLineCount(); ((CEdit *)(m_dlg->GetDlgItem(IDC_SHOWMESSAGE)))->LineScroll(linenum); if(!m_dlg->m_bClient) { } for(POSITION pos=m_dlg->m_connectionList.GetHeadPosition();pos!=NULL;) { } CClientSocket * t = (CClientSocket*)m_dlg->m_connectionList.GetNext(pos); if(t->m_hSocket!=this->m_hSocket) { } t->SendMessage(&temp);
}
BOOL CClientSocket::SendMessage(CPackMessg * msg) m_sfSocketFile= new CSocketFile(this); m_aSessionIn=new CArchive(m_sfSocketFile,CArchive::load); m_aSessionOut=new CArchive(m_sfSocketFile,CArchive::store); m_bClose=false; this->m_dlg=dlg;
{
if (m_aSessionOut != NULL)
{
msg->Serialize(*m_aSessionOut);
m_aSessionOut->Flush();
return TRUE;
}
else
{
//对方关闭了连接
m_bClose=true;
CloseSocket();
m_dlg->CloseSessionSocket();
return FALSE;
}
}
void CClientSocket::CloseSocket()
{
if(m_aSessionIn)
{
delete m_aSessionIn;
m_aSessionIn=NULL;
}
if(m_aSessionOut)
{
delete m_aSessionOut;
m_aSessionOut=NULL;
}
if(m_sfSocketFile)
{
delete m_aSessionOut;
m_sfSocketFile=NULL;
}
Close();
m_bInit=false;
m_bClose=true;
int CClientSocket::GetLocalHostName(CString &sHostName) //获得本地计算机名称
{
}
int CClientSocket::GetIpAddress(const CString &sHostName, CString &sIpAddress)//获得本地IP {
}
int CClientSocket::GetIpAddress(const CString &sHostName, BYTE &f0,BYTE &f1,BYTE &f2,BYTE &f3)//获得本地IP
{
struct hostent FAR * lpHostEnt=gethostbyname(sHostName); if(lpHostEnt==NULL) { struct hostent FAR * lpHostEnt=gethostbyname(sHostName); if(lpHostEnt==NULL) { } //获取IP LPSTR lpAddr=lpHostEnt->h_addr_list[0]; if(lpAddr) { } return 0; struct in_addr inAddr; memmove(&inAddr,lpAddr,4); //转换为标准格式 sIpAddress=inet_ntoa(inAddr); if(sIpAddress.IsEmpty()) sIpAddress=_T("没有取得"); //产生错误 sIpAddress=_T(""); return GetLastError(); char szHostName[256]; int nRetCode; nRetCode=gethostname(szHostName,sizeof(szHostName)); if(nRetCode!=0) { } sHostName=szHostName; return 0; //产生错误 sHostName=_T("没有取得"); return GetLastError();
}
CString CClientSocket::ErrorReason(int tag)
{
CString result; switch(tag) { case WSANOTINITIALISED: result="A successful AfxSocketInit must occur before using this API."; break; result="the network subsystem failed"; break; result="The specified address is already in use"; break; result="A blocking Windows Sockets call is in progress"; break; result="The specified address is not available from the local machine"; break; result="Addresses in the specified family cannot be used with this socket"; break; result="The attempt to connect was rejected"; break; } //获取IP LPSTR lpAddr=lpHostEnt->h_addr_list[0]; if(lpAddr) { } return 0; struct in_addr inAddr; memmove(&inAddr,lpAddr,4); f0=inAddr.S_un.S_un_b.s_b1; f1=inAddr.S_un.S_un_b.s_b2; f2=inAddr.S_un.S_un_b.s_b3; f3=inAddr.S_un.S_un_b.s_b4; f0=f1=f2=f3=0; return GetLastError(); case WSAENETDOWN: case WSAEADDRINUSE: case WSAEINPROGRESS: case WSAEADDRNOTAVAIL: case WSAEAFNOSUPPORT: case WSAECONNREFUSED:
} } return result; result="A destination address is required"; break; result="The nSockAddrLen argument is incorrect"; break; result="Invalid host address"; break; result="The socket is already connected."; break; result="No more file descriptors are available"; break; result="The network cannot be reached from this host at this time"; break; result="No buffer space is available. The socket cannot be connected"; break; result="The descriptor is not a socket"; break; result="Attempt to connect timed out without establishing a connection"; break; result="The socket is marked as nonblocking and the connection cannot be completed break; result="unknown error"; case WSAEFAULT: case WSAEINVAL: case WSAEISCONN: case WSAEMFILE: case WSAENETUNREACH: case WSAENOBUFS: case WSAENOTSOCK: case WSAETIMEDOUT: case WSAEWOULDBLOCK: immediately."; default:
// ServerSocket.cpp : implementation file
//
#include "stdafx.h"
#include "chat.h"
#include "ServerSocket.h"
#include "chatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////////////// // CServerSocket
// Do not edit the following lines, which are needed by ClassWizard. #if 0
BEGIN_MESSAGE_MAP(CServerSocket, CSocket)
//{{AFX_MSG_MAP(CServerSocket) //}}AFX_MSG_MAP
// 0 END_MESSAGE_MAP() #endif
///////////////////////////////////////////////////////////////////////////// // CServerSocket member functions
BOOL CServerSocket::Init(UINT port, CChatDlg* dlg)
{
m_uPort=port; m_dlg=dlg; if(Create(m_uPort)==FALSE) { } if(this->Listen()==FALSE) { } m_dlg->SetDlgItemText(IDC_SHOWMESSAGE,"服务器创建成功!"); return TRUE; AfxMessageBox("服务器监听错误!"); return FALSE; AfxMessageBox("服务器套接字创建失败!"); return FALSE;
//有连接接入的时候触发该事件
void CServerSocket::OnAccept(int nErrorCode)
{
}
// ServerSocket.cpp : implementation file
//
#include "stdafx.h"
#include "chat.h"
#include "ServerSocket.h"
#include "chatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////////////// // CServerSocket
// Do not edit the following lines, which are needed by ClassWizard. #if 0
BEGIN_MESSAGE_MAP(CServerSocket, CSocket)
//{{AFX_MSG_MAP(CServerSocket) //}}AFX_MSG_MAP
// 0 // TODO: Add your specialized code here and/or call the base class m_dlg->ProcessPendingAccept(); CSocket::OnAccept(nErrorCode); END_MESSAGE_MAP() #endif
///////////////////////////////////////////////////////////////////////////// // CServerSocket member functions
BOOL CServerSocket::Init(UINT port, CChatDlg* dlg)
{
}
//有连接接入的时候触发该事件
void CServerSocket::OnAccept(int nErrorCode) {
} // TODO: Add your specialized code here and/or call the base class m_dlg->ProcessPendingAccept(); CSocket::OnAccept(nErrorCode); m_dlg=dlg; if(Create(m_uPort)==FALSE) { } if(this->Listen()==FALSE) { } m_dlg->SetDlgItemText(IDC_SHOWMESSAGE,"服务器创建成功!"); return TRUE; AfxMessageBox("服务器监听错误!"); return FALSE; AfxMessageBox("服务器套接字创建失败!"); return FALSE;