Socket编程,以前在IPv4上运行没问题,现在机器是IPv6上运行不了,请问怎么修改既能支持IPv4又支持IPv6?

gxingmin 2013-02-06 01:46:53
#pragma once
#include "afxsock.h"

class CServerConnectSoc :public CAsyncSocket
{
public:
CServerConnectSoc(void);
~CServerConnectSoc(void);
public:
CCriticalSection* m_pCriticalSection;
CGtpDataServerDlg * thisDlg;
CWinThread* m_pThread;
HANDLE hConnectClose; //连接关闭信号量
HANDLE hExitedWorkThread; //指示已经成功关闭工作线程
HANDLE hReceiveFinished; //指示完成了数据接收工作,否则,不能退出线程
BOOL bIsReceiving; //指示是否在接收数据,如果是 则主线程需要等待
CWinThread* m_CheckThead; //数据读取 命令发送等工作 线程
DWORD m_nThreadID; //工作线程ID 用户与主线程通讯联络使用
int Index ; //在Array结构数组中的下标 该下标在初始化时就确定了 不再改变 用来提高访问效率
CString FILEN;
DWORD GetTimes;
BOOL m_fConnected; //Socket连接状态

TCHAR m_sendBuff[MAX_BUFF+4];
int m_nSendDataLen;
int m_nBytesSent;
TCHAR m_recvBuff[MAX_BUFF+4];
int m_nRecvDataLen;
int m_nBytesRecv;
BOOL m_bReadDataLength;
void AsyncSendBuff(void* lpBuf, int nBufLen);


// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CConnectSoc)
public:
virtual void OnClose(int nErrorCode);
virtual void OnReceive(int nErrorCode);
virtual void OnSend(int nErrorCode);
virtual int Receive(void* lpBuf, int nBufLen, int nFlags = 0);
virtual int Send(const void* lpBuf, int nBufLen, int nFlags = 0);
protected:
void DoAsyncSendBuff();
};



#include "StdAfx.h"
#include "GtpDataServer.h"
#include "ServerConnect.h"

/////////////////////////////////////////////////////////////////////////////
// CConnectSoc
//该线程负责启动巡检 发送命令超时等控制
UINT ServerCheckDataThread(LPVOID pParam)
{
CString str;
DWORD dwRes;
HANDLE hArray[2];
CServerConnectSoc * thisSoc = (CServerConnectSoc *)pParam;
str.Format(L"%x",thisSoc->m_nThreadID);
hArray[0] = thisSoc->hConnectClose;
do
{
//启动轮询 判断超时,如果连续N次超时,则关闭该连接
dwRes = WaitForMultipleObjects(1,hArray,FALSE,5);//等待指定事件发生
switch(dwRes)
{
case WAIT_OBJECT_0:
SetEvent(thisSoc->hExitedWorkThread);
thisSoc->m_CheckThead=NULL;
return 0;
break;
case WAIT_TIMEOUT://超时
//记录读取事件或超时事件的时间 已备读取函数判断来了数据包后没有
break;

//超时完毕

default:
//错误 报告错误
break;
}
}
while(1);
SetEvent(thisSoc->hExitedWorkThread);
thisSoc->m_CheckThead=NULL;
return 0;
}

//当创建该类时 已经就成功连接上,直接打开工作线程即可
CServerConnectSoc::CServerConnectSoc(void)
{
bIsReceiving=FALSE;
GetTimes=0;
m_nBytesSent = m_nSendDataLen = 0;
m_nRecvDataLen = sizeof(int); // initialize for 4 byte data length
m_nBytesRecv = 0;
m_bReadDataLength = TRUE;
m_CheckThead=NULL;
m_fConnected=TRUE;
hConnectClose= CreateEvent(NULL, TRUE, FALSE, NULL);
hReceiveFinished=CreateEvent(NULL, TRUE, FALSE, NULL);
hExitedWorkThread=CreateEvent(NULL, TRUE, FALSE, NULL);
m_CheckThead=AfxBeginThread(ServerCheckDataThread,this,THREAD_PRIORITY_HIGHEST);
thisDlg =(CGtpDataServerDlg *)AfxGetApp()->m_pMainWnd;
}


CServerConnectSoc::~CServerConnectSoc(void)
{
DWORD dwRes=-1;
if(m_CheckThead!=NULL) //如果该线程句柄还存在 则说明还没有关闭
{
//先关闭工作线程 该线程负责轮询各IP下管辖的信息
SetEvent(hConnectClose);
dwRes = WaitForSingleObject(hExitedWorkThread, INFINITE);

switch(dwRes)
{
case WAIT_OBJECT_0:
m_pThread->PostThreadMessage(WM_QUIT,0,0);
break;
case WAIT_TIMEOUT:
TerminateThread(m_CheckThead,0);
m_CheckThead=NULL;
break;
default:;
break;
}
}
thisDlg=NULL;
}
void CServerConnectSoc::OnClose(int nErrorCode)
{
// passive close
m_fConnected=FALSE;
ShutDown();
Close();
Sleep(20);
DWORD dwRes=-1;
if(bIsReceiving)
{
dwRes = WaitForSingleObject(hReceiveFinished,INFINITE);
switch(dwRes)
{
case WAIT_OBJECT_0:
//Sleep(2000);
break;
case WAIT_TIMEOUT:
break;
default:;
break;
}
dwRes=-1;
}

TRACE(_TEXT("CConnectSoc::OnClose: CAsyncSocket::Close() called\n"));
if(m_CheckThead!=NULL)
{
//先关闭工作线程 该线程负责轮询各IP下管辖的信息
SetEvent(hConnectClose);
dwRes = WaitForSingleObject(hExitedWorkThread, INFINITE);

switch(dwRes)
{
case WAIT_OBJECT_0:
m_pThread->PostThreadMessage(WM_QUIT,0,0);
break;
case WAIT_TIMEOUT:
TerminateThread(m_CheckThead,0);
m_CheckThead=NULL;
break;
default:;
break;
}
}
else
{
m_pThread->PostThreadMessage(WM_QUIT,0,0);
}
Sleep(1000);
CAsyncSocket::OnClose(nErrorCode);
}
void CServerConnectSoc::OnReceive(int nErrorCode)
{
bIsReceiving=TRUE;
ResetEvent(hReceiveFinished);
int nRead = 0;
nRead = Receive(m_recvBuff ,4096);

switch (nRead)
{
case 0:
break;
case SOCKET_ERROR:
if (GetLastError() != WSAEWOULDBLOCK)
{
AfxMessageBox(_TEXT("Socket Error. Unable to read data."));
}
else
{
TRACE(_TEXT("CConnectSoc: WARNING: WSAEWOULDBLOCK on a Receive in OnReceive\n"));
}
break;
default:
m_recvBuff[nRead] = '\0';
CFile file;
GetTimes++;
if(GetTimes%10==0)
{
file.Open(FILEN,CFile::typeBinary|CFile::modeWrite|CFile::shareDenyNone|CFile::modeNoTruncate|CFile::modeCreate);
file.SeekToEnd();
file.Write((void *)&GetTimes,4);
file.Close();
}
if(m_fConnected)
{
Sleep(10);
AsyncSendBuff(m_recvBuff,nRead );
}
}

TRACE(_TEXT("CConnectSoc::OnReceive(int nErrorCode = %d) nRead = %d\n"), nErrorCode, nRead);
bIsReceiving=FALSE;
SetEvent(hReceiveFinished);
}


void CServerConnectSoc::OnSend(int nErrorCode)
{
// we called CAsyncSocket::Send and it returned WSAEWOULDBLOCK
OutputDebugString(_TEXT("CConnectSoc::OnSend\n"));
DoAsyncSendBuff();
CAsyncSocket::OnSend(nErrorCode);
}

void CServerConnectSoc::AsyncSendBuff(void* lpBuf, int nBufLen)
{
// We don't queue up data here.
// If you are going to queue up data packet, it would be better to limit the size
// of the queue and remember to clear up the queue whenever the current packet has been sent.
if (m_nSendDataLen != 0 || nBufLen > MAX_BUFF)
{
TCHAR szError[256];
wsprintf(szError, _TEXT("CConnectSoc::AsyncSendBuff() can't accept more data\n"));
AfxMessageBox (szError);
return;
}
else
{
if (nBufLen > MAX_BUFF)
{
TCHAR szError[256];
wsprintf(szError, _TEXT("CConnectSoc::AsyncSendBuff() oversize buffer.\n"));
AfxMessageBox (szError);
return;
}

memcpy(m_sendBuff, lpBuf, nBufLen);
m_nSendDataLen = nBufLen ;
m_nBytesSent = 0;
DoAsyncSendBuff();
}
}

void CServerConnectSoc::DoAsyncSendBuff()
{
while (m_nBytesSent < m_nSendDataLen)
{
int nBytes;

if ((nBytes = Send((LPCTSTR)m_sendBuff + m_nBytesSent, m_nSendDataLen - m_nBytesSent))
== SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK)
break;
else
{
TCHAR szError[256];
wsprintf(szError, _TEXT("Server Socket failed to send: %d"), GetLastError());
Close();
AfxMessageBox (szError);
m_pThread->PostThreadMessage(WM_QUIT,0,0);
m_nBytesSent = 0;
m_nSendDataLen = 0;//sizeof(int);
return;
}
}
else
{
m_nBytesSent += nBytes;
}
}

if (m_nBytesSent == m_nSendDataLen)
{
m_nBytesSent = m_nSendDataLen = 0;
}
}

int CServerConnectSoc::Receive(void* lpBuf, int nBufLen, int nFlags)
{
OutputDebugString(_TEXT("CConnectSoc::Receive\n"));
return CAsyncSocket::Receive(lpBuf, nBufLen, nFlags);
}

int CServerConnectSoc::Send(const void* lpBuf, int nBufLen, int nFlags)
{
OutputDebugString(_TEXT("CConnectSoc::Send\n"));
return CAsyncSocket::Send(lpBuf, nBufLen, nFlags);
}

...全文
155 3 点赞 打赏 收藏 举报
写回复
3 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
晴天恋 2013-02-07
呵呵。来学习一下。呵呵。
  • 打赏
  • 举报
回复
jimette 2013-02-06
http://blog.csdn.net/byxdaz/article/details/643059
  • 打赏
  • 举报
回复
玉宇逍遥 2013-02-06
去看一下《UNIX网络编程_卷1_套接字联网API》吧,里面有教你怎么做的方法。
  • 打赏
  • 举报
回复
相关推荐
发帖
VC/MFC
加入

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2013-02-06 01:46
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……