解决CSocket高数据传输问题
这个是自己项目中发现的问题,所以这个不一定适用于你的。
仅供参考。
头文件:
ESSocket.h
- // ESSocket.h : header file
- //
- #ifndef ESSOCKET_H
- #define ESSOCKET_H
- #pragma once
- #include <Winsock2.h> // win32 socket stuff
- #define WM_LTC_WINSOCK_MSG_RECEIVED WM_USER+001
- /////////////////////////////////////////////////////////////////////////////
- // CESSocket class - a replacement-class for CSocket of MFC
- //
- // CESSocket should not block on high data rate, as CSocket does. However,
- // CESSocket is not a full replacement of CSocket.
- class CESSocket
- {
- friend class CMessageTargetWnd;
- public:
- CESSocket();
- virtual ~CESSocket();
- protected:
- virtual void OnReceive(int nErrorCode);
- public:
- bool Create();
- bool Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
- int Send(const void* lpBuf, int nBufLen, int nFlags = 0);
- int Receive(void* lpBuf, int nBufLen, int nFlags = 0);
- void Close();
- int GetLastError();
- private:
- CMessageTargetWnd *m_pWndMessageTarget;
- SOCKET m_sock;
- int m_nLastError;
- static int m_nInstanceCount;
- };
- //Helper class CMessageTargetWnd
- class CMessageTargetWnd : public CWnd
- {
- public:
- CMessageTargetWnd(CESSocket*);
- protected:
- LRESULT OnDataReceive(WPARAM, LPARAM);
- DECLARE_MESSAGE_MAP()
- private:
- CESSocket *m_pESSocket;
- };
- #endif // ESSOCKET_H
ESSocket.cpp
- // ESSocket.cpp
- //
- #ifndef WINVER
- #if _MSC_VER <= 1200 // up to VC6.0
- #define WINVER 0x0400
- #else
- #define WINVER 0x0501
- #endif
- #endif
- #include <afxwin.h>
- #include "ESSocket.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CESSocket class
- //
- int CESSocket::m_nInstanceCount = 0;
- CESSocket::CESSocket()
- {
- m_pWndMessageTarget = new CMessageTargetWnd(this);
- m_sock = 0;
- m_nLastError = 0;
- // keep track of #of instances; CESSocket is not designed to support multiple instances!
- m_nInstanceCount++;
- ASSERT(m_nInstanceCount == 1);
- }
- CESSocket::~CESSocket()
- {
- Close(); // just in case the application did not call Close()
- if (WSACleanup())
- TRACE(_T("WSACleanup() failed\n"));
- if (m_pWndMessageTarget)
- {
- if (::IsWindow(m_pWndMessageTarget->m_hWnd))
- VERIFY(m_pWndMessageTarget->DestroyWindow());
- delete m_pWndMessageTarget;
- }
- m_nInstanceCount--;
- }
- void CESSocket::OnReceive(int nErrorCode)
- {
- ASSERT(false); // derived class does not provide an implementation for OnReceive()
- TRACE(_T("virtual OnReceive() called"));
- }
- bool CESSocket::Create()
- {
- WSADATA WSAData;
- ASSERT(m_sock == 0); // call Create only once!
- m_nLastError = 0;
- if (m_nInstanceCount != 1)
- {
- ASSERT(false);
- return false; // this class does not support more than one instance
- }
- if (!::IsWindow(m_pWndMessageTarget->m_hWnd))
- {
- CWnd *pWndParent = CWnd::GetDesktopWindow();
- // This call may fail on Win98 / Unicode builds! use non- Unicode version in these cases
- m_pWndMessageTarget->CWnd::Create(NULL, _T("cessocket_message_sink"), WS_CHILD,
- CRect(0, 0, 20, 20), pWndParent, 0);
- if (!::IsWindow(m_pWndMessageTarget->m_hWnd))
- {
- ASSERT(false);
- TRACE(_T("Creation or message- target window failed\n"));
- return false;
- }
- if (WSAStartup(MAKEWORD(1,1), &WSAData) == 0)
- {
- m_sock = socket(PF_INET, SOCK_STREAM, 0);
- if (m_sock == INVALID_SOCKET)
- {
- m_nLastError = WSAGetLastError();
- m_sock = 0;
- WSACleanup();
- VERIFY(m_pWndMessageTarget->DestroyWindow());
- TRACE(_T("Socket creation failed\n"));
- return false;
- }
- }
- else
- {
- TRACE(_T("WSAStartup failed\n"));
- return false;
- }
- }
- else
- {
- ASSERT(m_sock != 0);
- ASSERT(false); // target window and socket already exists - Create should be called only once!
- }
- return true;
- }
- bool CESSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
- {
- #ifdef _UNICODE
- USES_CONVERSION; // for W2A macro
- #endif
- PHOSTENT phe;
- SOCKADDR_IN dest_sin;
- struct in_addr address;
- if (!m_pWndMessageTarget)
- {
- ASSERT(false);
- return false;
- }
- if (m_sock == 0)
- {
- // Did you miss to call Create()? Did you already close the socket?
- ASSERT(false);
- return false;
- }
- // Note: Once Close() is called, you cannot re-use the socket!
- // CESSocket class is neither designed to support multiple
- // instances not to re-use once closed connections. You must
- // delete the current instance and create a new one for a
- // re-connection or a connection to a different server.
- memset(&dest_sin, 0, sizeof dest_sin);
- dest_sin.sin_family = AF_INET;
- dest_sin.sin_port = htons(nHostPort);
- if (_tcschr(lpszHostAddress, '.') == 0)
- {
- #ifdef _UNICODE
- phe = gethostbyname(W2A(lpszHostAddress));
- #else
- phe = gethostbyname(lpszHostAddress);
- #endif
- if (phe == NULL)
- {
- m_nLastError = WSAGetLastError();
- TRACE(_T("gethostbyname failed\n"));
- return false;
- } // if
- memcpy((char FAR *)&(dest_sin.sin_addr), phe->h_addr, phe->h_length);
- } // if
- else
- {
- #ifdef _UNICODE
- address.s_addr = inet_addr(W2A(lpszHostAddress));
- #else
- address.s_addr = inet_addr(lpszHostAddress);
- #endif
- dest_sin.sin_addr = address;
- }
- if (connect(m_sock, (LPSOCKADDR)&dest_sin, sizeof dest_sin))
- {
- m_nLastError = WSAGetLastError();
- TRACE(_T("Connection to server failed.\nCheck host-id and port# !\n"));
- return false;
- }
- if (WSAAsyncSelect(m_sock, *m_pWndMessageTarget, WM_LTC_WINSOCK_MSG_RECEIVED, FD_READ) > 0)
- {
- m_nLastError = WSAGetLastError();
- TRACE(_T("WSAAsyncSelect failed\n"));
- return false;
- } // if
- TRACE(_T("Connection to server OK\n"));
- m_nLastError = 0;
- ASSERT(m_sock != 0);
- return true; // success
- }
- int CESSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
- {
- if (send(m_sock, (const char*)lpBuf, nBufLen, nFlags) == SOCKET_ERROR)
- {
- m_nLastError = WSAGetLastError();
- return false;
- }
- m_nLastError = 0;
- return true;
- }
- int CESSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
- {
- int nBytes = 0;
- if ((nBytes = recv(m_sock, (char*)lpBuf, nBufLen, nFlags)) == SOCKET_ERROR)
- {
- m_nLastError = WSAGetLastError();
- return false;
- }
- m_nLastError = 0;
- return nBytes;
- }
- void CESSocket::Close()
- {
- if (m_sock)
- {
- m_nLastError = 0;
- ASSERT(m_pWndMessageTarget);
- // stop receiving messages
- WSAAsyncSelect(m_sock, *m_pWndMessageTarget, 0, 0);
- if (closesocket(m_sock) == SOCKET_ERROR)
- m_nLastError = WSAGetLastError();
- m_sock = 0;
- TRACE(_T("Socket closed\n"));
- }
- }
- int CESSocket::GetLastError()
- {
- return m_nLastError;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CMessageTargetWnd class
- //
- CMessageTargetWnd::CMessageTargetWnd(CESSocket *pESSocket)
- {
- m_pESSocket = pESSocket;
- }
- LRESULT CMessageTargetWnd::OnDataReceive(WPARAM wParam, LPARAM lParam)
- {
- m_pESSocket->OnReceive(HIWORD(lParam));
- return 0;
- }
- BEGIN_MESSAGE_MAP(CMessageTargetWnd, CWnd)
- ON_MESSAGE(WM_LTC_WINSOCK_MSG_RECEIVED, OnDataReceive)
- END_MESSAGE_MAP()
解决CSocket高数据传输问题的更多相关文章
- 解决Safari高版本浏览器中默认禁用第三方COOKIE(含demo)
前段时间在项目里遇到了一个比较头疼的问题,就是高版本的Safari中默认会阻止第三方cookie,这使得使用Safari浏览器的用户无法按照正常的业务逻辑进行操作. 问题展现 知识点 什么是第三方co ...
- Android中ListView嵌套GridView的简单消息流UI(解决宽高问题)
最近搞一个项目,需要用到类似于新浪微博的消息流,即每一项有文字.有九宫格图片,因此这就涉及到ListView或者ScrollView嵌套GridView的问题.其中GridView的高度问题在网上都很 ...
- Java集群--大型网站是怎样解决多用户高并发访问的
时间过得真快,再次登录博客园来写博,才发现距离上次的写博时间已经过去了一个月了,虽然是因为自己找了实习,但这也说明自己对时间的掌控能力还是没那么的强,哈哈,看来还需不断的努力啊!(这里得特别说明一下本 ...
- 利用redis + lua解决抢红包高并发的问题
抢红包的需求分析 抢红包的场景有点像秒杀,但是要比秒杀简单点.因为秒杀通常要和库存相关.而抢红包则可以允许有些红包没有被抢到,因为发红包的人不会有损失,没抢完的钱再退回给发红包的人即可.另外像小米这样 ...
- 解决vs-code高cpu占用率问题
(microsoft.vscode.cpp.extension.darwin进程高cpu占用问题) 免费的vs-code现在已经成为mac/linux平台的码农新宠,毕竟从windows平台开发vir ...
- oracle解决导入高版本dmp报错问题:IMP-00058: ORACLE error 12547 encountered
低版本oracle导入高版本的dmp时,导过的人都应该清楚,直接导入是会报错的,报错信息如下,其实解决这个问题很简单, 只要修改一下dmp内的版本号就可以了. 修改版本不能随便使用文本工具打开,否知会 ...
- 解决eclipse高版本JDK编译的项目到低版本JDK服务器上不能运行的问题
错误提示信息:Unsupported major.minor version 52.0,意思是说,当前jdk的版本不支持更高版本jdk编译出来的class文件. 我的编译环境,eclipse使用的是j ...
- Redis:解决分布式高并发修改同一个Key的问题
本篇文章是通过watch(监控)+mutil(事务)实现应用于在分布式高并发处理等相关场景.下边先通过redis-cli.exe来测试多个线程修改时,遇到问题及解决问题. 高并发下修改同一个key遇到 ...
- 翻屏类 h5 适配方案:解决宽高自适应难题
表格 图片等 宽度自适应 :width:100%; box-sizing: border-box; 基于淘宝适配方案flexible + 翻屏h5 适配方案adaptive flexible解读及 ...
随机推荐
- PAT甲级——A1124 Raffle for Weibo Followers
John got a full mark on PAT. He was so happy that he decided to hold a raffle(抽奖) for his followers ...
- springcloud系列13 config的客户端使用
config客户端的使用: 也是首先要引入依赖: <dependency> <groupId>org.springframework.cloud</groupId> ...
- java笔试之自守数
自守数是指一个数的平方的尾数等于该数自身的自然数.例如:25^2 = 625,76^2 = 5776,9376^2 = 87909376.请求出n以内的自守数的个数 接口说明 /*功能: 求出n以内的 ...
- Pascal代码自动格式化
const WEnter=; key=; next_line:..WEnter]of string=(';','begin','else','then','repeat','do','var'); k ...
- Python全栈开发:协程代码实例
协程代码1 #!/usr/bin/env python # -*- coding;utf-8 -*- # 导入协程模块 """ 协程工作原理 ""&q ...
- Python全栈开发:模块
模块,用一砣代码实现了某个功能的代码集合. 参考资源:http://www.cnblogs.com/alex3714/articles/5161349.html 类似于函数式编程和面向过程编程,函数式 ...
- Stopwatch 计时器类
C#_Stopwatch 类 命名空间:System.Diagnostics Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.在典型的 Stopwatc ...
- MongDB4.1-入门学习之下载安装配置
下载安装配置三步走 下载,MongoDB官网下载中心 下载_.msi_安装版 安装,注意以下几个步骤: Choose Setup Type: Please Choose Custom Custom S ...
- Idea安装Mevn
1.下载mevn安装包. 下载地址:http://maven.apache.org/ 点击Download 2.下面这两个选哪个都可以,取决于你用什么方式解压 3.把下载好的安装包解压到一个没有中文的 ...
- thinkphp 自动验证
自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创建数据对象的时候自动进行数据验证. 大理石平台价格表 验证规则 数据验证可以进行数据类型.业务规则.安全判断等方面的验证 ...