INTERNET编程之CSOCKET编程实现UDP连接

今天我们用CSocket实现昨天用SOCKET实现的异步套接字的功能吧. 

如果你还是不知道怎么实现用户自定义消息的话,你也不用急.今天,我们并不需要用自定义消息的,我们只需要从CSOCKET来派生我们对SOCKET的实现就行了.我们先来讲讲实现流程吧:

首先,创建套接字 - 绑定端口 - 发送/接受数据. - 关闭套接字

好,我们就沿着这个这个轨迹来写吧.

首先,我们派生一个我们的CMySocket:代码如下:

头文件:

#if !defined(AFX_MYSOCKET_H__556DCBE5_E9F7_4285_A0F9_3B30A9CABB6D__INCLUDED_)
#define AFX_MYSOCKET_H__556DCBE5_E9F7_4285_A0F9_3B30A9CABB6D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MySocket.h : header file
//

 

/
// CMySocket command target

class CMySocket : public CSocket
{
// Attributes
public:
 HWND    m_hWnd;

 CString m_strHost;
 CString m_strSend;
 CString m_strRecv;

// Operations
public:
 CMySocket();
 virtual ~CMySocket();

public:

// Overrides
public:
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CMySocket)
 public:
 virtual void OnSend(int nErrorCode);
 virtual void OnReceive(int nErrorCode);
 //}}AFX_VIRTUAL

 // Generated message map functions
 //{{AFX_MSG(CMySocket)
  // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

// Implementation
protected:

private:
};

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYSOCKET_H__556DCBE5_E9F7_4285_A0F9_3B30A9CABB6D__INCLUDED_)

实现文件:

// MySocket.cpp : implementation file
//

#include "stdafx.h"
#include "MFCCSocket.h"
#include "MySocket.h"

#include "MFCCSocketDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CMySocket

CMySocket::CMySocket()
{
 m_strHost = _T("");
 m_strSend = _T("");
 m_strRecv = _T("");
}

CMySocket::~CMySocket()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMySocket, CSocket)
 //{{AFX_MSG_MAP(CMySocket)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0

/
// CMySocket member functions

void CMySocket::OnSend( int nErrorCode )
{
 CSocket::OnSend( nErrorCode );
 static int  i = 0;
 if ( i == 0 )
 {
  i = 1; return ;
 }

 char  buffer[MAX_PATH] = {0};
 SOCKADDR_IN addrTo;
 HOSTENT * pHost = NULL;
 int   nLen,nRet;
 
 nLen  = sizeof(SOCKADDR);
 pHost = gethostbyname( m_strHost );
 
 addrTo.sin_addr.S_un.S_addr = *((DWORD*)pHost->h_addr_list[0]);
 addrTo.sin_family   = AF_INET;
 addrTo.sin_port    = htons(4443);
 memset( addrTo.sin_zero, 0, sizeof(addrTo.sin_zero) );
 
 m_strSend += "/t/t/t/t";
 do
 {
  strncpy( buffer, m_strSend, MAX_PATH - 1 );
  nRet  = ( buffer, strlen(buffer), (SOCKADDR*)&addrTo, nLen );
  if( SOCKET_ERROR == nRet )
  {
   sprintf( buffer, "发送数据失败!有可能出现数据丢失!/n错误原因:%d", GetLastError() );
   AfxMessageBox( buffer );
   break ;
  }
  buffer[nRet] = 0;
  m_strSend.Delete( 0, nRet );
  if ( m_strSend.GetLength() <= 0 ) break ;
  memset( buffer, 0, MAX_PATH );

 } while( TRUE );
 
 m_strSend = _T("");
}

void CMySocket::OnReceive( int nErrorCode )
{
 CString strRecv = _T("");
 char buffer[MAX_PATH] = {0};
 
 SOCKADDR_IN addrFrom;
 HOSTENT * pHost = NULL;
 int   nLen,nRet;
 
 nLen = sizeof(SOCKADDR);
 do
 {
  nRet = ReceiveFrom( buffer, MAX_PATH, (SOCKADDR*)&addrFrom, &nLen );
  if( SOCKET_ERROR == nRet )
  {
   sprintf( buffer, "接收数据失败!错误原因:%d", GetLastError() );
   AfxMessageBox( buffer );
   return ;
  }
  buffer[nRet] = 0; strRecv += buffer;
  if ( strRecv.Find("/t/t/t/t") >= 0 )
  {
   strRecv.Replace( _T("/t/t/t/t"), _T("/r/n" ) );
   break;
  }
  memset( buffer, 0, MAX_PATH );
  
 } while( TRUE );
 
 pHost = gethostbyaddr( (char*)&addrFrom.sin_addr.S_un.S_addr, 4, AF_INET );
 m_strRecv.Format("%s(%s) : /r/n%s",pHost->h_name, inet_ntoa(addrFrom.sin_addr), strRecv );
 
 int nPos,nMin,nMax;
 ((CMFCCSocketDlg*)CWnd::FromHandle(m_hWnd))->GetDlgItem(IDC_EDIT_STRING)->GetWindowText( strRecv );
 nPos = strRecv.GetLength();
 strRecv += m_strRecv;
 ((CMFCCSocketDlg*)CWnd::FromHandle(m_hWnd))->GetDlgItem(IDC_EDIT_STRING)->SetWindowText( strRecv );
 ((CMFCCSocketDlg*)CWnd::FromHandle(m_hWnd))->GetDlgItem(IDC_EDIT_STRING)->GetScrollRange ( SB_VERT, &nMin, &nMax );
 ((CMFCCSocketDlg*)CWnd::FromHandle(m_hWnd))->GetDlgItem(IDC_EDIT_STRING)->SetScrollPos ( SB_VERT, nMax, TRUE );
 ((CEdit*)((CMFCCSocketDlg*)CWnd::FromHandle(m_hWnd))->GetDlgItem(IDC_EDIT_STRING))->SetSel( nPos,strRecv.GetLength() );
 m_strRecv = _T("");

 CSocket::OnReceive( nErrorCode );
}
好了,这就是我们的CMySocket了.我们来用我们的套接字来创建并绑定吧:(BOOL CMFCCSocketDlg::OnInitDialog()中实现)

char buffer[MAX_PATH] = {0};
 if( !m_Socket.Create( 4443, SOCK_DGRAM,NULL ) )
 {
  sprintf( buffer, "创建套接字失败!错误原因:%d", GetLastError() );
  MessageBox( buffer );
  PostQuitMessage(0);
 }

 m_Socket.m_hWnd = m_hWnd;

接着,我们就要实现发送接收数据了,实际上在我们重载CSOCKET的时候,我们已经实现了发送接收的代码了.而且这里实现的接受和发送是没有长度限制的(精华哦!).

好,我们就来看看我是怎么来发送的(接收是自动接收,不需要再处理了,因为在重载的时候已经实现了这个虚函数了.)

void CMFCCSocketDlg::OnBtnSend()
{
 // TODO: Add your control notification handler code here
 UpdateData();

 char buffer[MAX_PATH] = {0};
 HOSTENT *pHost = NULL;
 m_Socket.m_strHost = m_strHost;
 m_Socket.m_strSend = m_strSend;

 if ( m_strHost.GetLength() <= 0  )
 {
  MessageBox( _T("请填写主机地址!") );
  return ;
 }
 if ( m_strSend.GetLength() <= 0 )
 {
  MessageBox( _T("发送消息不能为空!") );
  return ;
 }
 pHost = gethostbyname( m_strHost );
 if ( !pHost )
 {
  sprintf( buffer, "无法解析服务器地址!错误原因:%d", WSAGetLastError() );
  MessageBox( buffer );
  return ;
 }

 m_Socket.OnSend(0);

 m_strSend = _T("");

 UpdateData(FALSE);
}

接着,不就是关闭了嘛.实际上,你不需要显示的关闭它,它会在销毁的时候自动关闭的.呵呵.就写到这了.

看不懂那就没办法了哦!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值