在应用程序开始的时候,我们先应该初始话winSock 库,所以便会用到下面的一个函数。
BOOL AfxSocketInit( WSADATA* lpwsaData = NULL ); //用来初始化Socket,用WSAStartup();来初始化,在应用程序结束时他会自动调用WSACleanup()
我们在开始编程之前,应该调用这个函数,对Socket进行初始化。如果初始化成功返回非0 ,否则返回0.
可能人会问,这个函数加载的是那个版本的Socket库呢?通过查看底层代码,我们发现,他加载的是1.1版本的Socket
注意:这个函数只能在你自己应用程序的 CXXWinApp::InitInstance 中初始化.在初始化前还要记得加入头文件Afxsock.h
我服务器端程序 为 NetChatServer 所以我在的CNetChatServerApp::InitInstance()中加入
/CNetChatServerApp::InitInstance()///
if(!AfxSocketInit())
{
AfxMessageBox(_T("Socket 库初始化出错!"));
return false;
}
m_iSocket 是一个 CServerSocket*的 指针 ,CServerSocket类是一个我们自己的类我会在后面给出相应代码,他继承于CSocket类。
m_iSocket = new CServerSocket(); // 1.动态创建一个服务器Socket对象。
if(!m_iSocket)
{
AfxMessageBox(_T("动态创建服务器套接字出错!"));
return false;
}
接着创建套接字
if(!m_iSocket->Create(8989))
{
AfxMessageBox(_T("创建套接字错误!"));
m_iSocket->Close();
return false;
}
其中8989 是指定的端口号,但是要注意在保存我们指定的8989端口前,这个端口是空闲的没有被其他进程所占用,那怎么查看端口是否被其他进程占用呢?
首先打开cmd 键入 netstat -aon
你会看到所有的TCP/UDP 信息 ,但是由于太多了不好查看,所以。我们再在最下面 tasklist|find “8989”
现在我们看到 我们没有找到任何 和8989端口相关的东西,所以说明8989端口没有被占用。
创建了套接字以后按照win32的步骤我们就应该 对bind端口。
但是MFC 不这样,应为MFC的Create内部已经调用了bind ,如下是MFC的底层代码
BOOL CAsyncSocket::Create(UINT nSocketPort, int nSocketType,long lEvent, LPCTSTR lpszSocketAddress)
{
if (Socket(nSocketType, lEvent))
{
if (Bind(nSocketPort,lpszSocketAddress))//调用了bind
return TRUE;
int nResult = GetLastError();
Close();
WSASetLastError(nResult);
}
return FALSE;
}
所以 我们不用在调用bind 了,直接对套接字进行监听
if(!m_iSocket->Listen())
{
AfxMessageBox(_T("监听失败!"));
m_iSocket->Close();
return false;
}
/
然后重载ExitInstance,退出时对进行清理
int CNetChatServerApp::ExitInstance()
{
if(m_iSocket)
{
delete m_iSocket;
m_iSocket = NULL;
}
return CWinApp::ExitInstance();
}
//
下面 来看下CServerSocket的具体实现
#pragma once
#include "ClientSocket.h"
class CServerSocket : public CSocket
{
public:
CServerSocket();
virtual ~CServerSocket();
public :
CPtrList m_listSockets;//用来保存服务器与所有客户端连接成功后的ClientSocket
public :
virtual void OnAccept(int nErrorCode);
};
#include "stdafx.h"
#include "NetChatServer.h"
#include "ServerSocket.h"
CServerSocket::CServerSocket()
{
}
CServerSocket::~CServerSocket()
{
}
void CServe