这个是自己项目中发现的问题,所以这个不一定适用于你的。

仅供参考。

头文件:

ESSocket.h

  1. // ESSocket.h : header file
  2. //
  3. #ifndef ESSOCKET_H
  4. #define ESSOCKET_H
  5.  
  6. #pragma once
  7.  
  8. #include <Winsock2.h> // win32 socket stuff
  9.  
  10. #define WM_LTC_WINSOCK_MSG_RECEIVED WM_USER+001
  11.  
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CESSocket class - a replacement-class for CSocket of MFC
  14. //
  15. // CESSocket should not block on high data rate, as CSocket does. However,
  16. // CESSocket is not a full replacement of CSocket.
  17.  
  18. class CESSocket
  19. {
  20. friend class CMessageTargetWnd;
  21.  
  22. public:
  23. CESSocket();
  24. virtual ~CESSocket();
  25.  
  26. protected:
  27. virtual void OnReceive(int nErrorCode);
  28.  
  29. public:
  30. bool Create();
  31. bool Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
  32. int Send(const void* lpBuf, int nBufLen, int nFlags = 0);
  33. int Receive(void* lpBuf, int nBufLen, int nFlags = 0);
  34. void Close();
  35. int GetLastError();
  36.  
  37. private:
  38. CMessageTargetWnd *m_pWndMessageTarget;
  39. SOCKET m_sock;
  40. int m_nLastError;
  41.  
  42. static int m_nInstanceCount;
  43. };
  44.  
  45. //Helper class CMessageTargetWnd
  46.  
  47. class CMessageTargetWnd : public CWnd
  48. {
  49. public:
  50. CMessageTargetWnd(CESSocket*);
  51.  
  52. protected:
  53. LRESULT OnDataReceive(WPARAM, LPARAM);
  54. DECLARE_MESSAGE_MAP()
  55.  
  56. private:
  57. CESSocket *m_pESSocket;
  58. };
  59.  
  60. #endif // ESSOCKET_H

ESSocket.cpp

  1. // ESSocket.cpp
  2. //
  3. #ifndef WINVER
  4. #if _MSC_VER <= 1200 // up to VC6.0
  5. #define WINVER 0x0400
  6. #else
  7. #define WINVER 0x0501
  8. #endif
  9. #endif
  10.  
  11. #include <afxwin.h>
  12. #include "ESSocket.h"
  13.  
  14. #ifdef _DEBUG
  15. #define new DEBUG_NEW
  16. #endif
  17.  
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CESSocket class
  20. //
  21.  
  22. int CESSocket::m_nInstanceCount = 0;
  23.  
  24. CESSocket::CESSocket()
  25. {
  26. m_pWndMessageTarget = new CMessageTargetWnd(this);
  27. m_sock = 0;
  28. m_nLastError = 0;
  29.  
  30. // keep track of #of instances; CESSocket is not designed to support multiple instances!
  31. m_nInstanceCount++;
  32. ASSERT(m_nInstanceCount == 1);
  33. }
  34.  
  35. CESSocket::~CESSocket()
  36. {
  37. Close(); // just in case the application did not call Close()
  38.  
  39. if (WSACleanup())
  40. TRACE(_T("WSACleanup() failed\n"));
  41.  
  42. if (m_pWndMessageTarget)
  43. {
  44. if (::IsWindow(m_pWndMessageTarget->m_hWnd))
  45. VERIFY(m_pWndMessageTarget->DestroyWindow());
  46.  
  47. delete m_pWndMessageTarget;
  48. }
  49.  
  50. m_nInstanceCount--;
  51. }
  52.  
  53. void CESSocket::OnReceive(int nErrorCode)
  54. {
  55. ASSERT(false); // derived class does not provide an implementation for OnReceive()
  56. TRACE(_T("virtual OnReceive() called"));
  57. }
  58.  
  59. bool CESSocket::Create()
  60. {
  61. WSADATA WSAData;
  62.  
  63. ASSERT(m_sock == 0); // call Create only once!
  64. m_nLastError = 0;
  65.  
  66. if (m_nInstanceCount != 1)
  67. {
  68. ASSERT(false);
  69. return false; // this class does not support more than one instance
  70. }
  71.  
  72. if (!::IsWindow(m_pWndMessageTarget->m_hWnd))
  73. {
  74. CWnd *pWndParent = CWnd::GetDesktopWindow();
  75.  
  76. // This call may fail on Win98 / Unicode builds! use non- Unicode version in these cases
  77. m_pWndMessageTarget->CWnd::Create(NULL, _T("cessocket_message_sink"), WS_CHILD,
  78. CRect(0, 0, 20, 20), pWndParent, 0);
  79.  
  80. if (!::IsWindow(m_pWndMessageTarget->m_hWnd))
  81. {
  82. ASSERT(false);
  83. TRACE(_T("Creation or message- target window failed\n"));
  84. return false;
  85. }
  86.  
  87. if (WSAStartup(MAKEWORD(1,1), &WSAData) == 0)
  88. {
  89. m_sock = socket(PF_INET, SOCK_STREAM, 0);
  90.  
  91. if (m_sock == INVALID_SOCKET)
  92. {
  93. m_nLastError = WSAGetLastError();
  94. m_sock = 0;
  95. WSACleanup();
  96. VERIFY(m_pWndMessageTarget->DestroyWindow());
  97. TRACE(_T("Socket creation failed\n"));
  98. return false;
  99. }
  100. }
  101. else
  102. {
  103. TRACE(_T("WSAStartup failed\n"));
  104. return false;
  105. }
  106. }
  107. else
  108. {
  109. ASSERT(m_sock != 0);
  110. ASSERT(false); // target window and socket already exists - Create should be called only once!
  111. }
  112.  
  113. return true;
  114. }
  115.  
  116. bool CESSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
  117. {
  118. #ifdef _UNICODE
  119. USES_CONVERSION; // for W2A macro
  120. #endif
  121.  
  122. PHOSTENT phe;
  123. SOCKADDR_IN dest_sin;
  124. struct in_addr address;
  125.  
  126. if (!m_pWndMessageTarget)
  127. {
  128. ASSERT(false);
  129. return false;
  130. }
  131.  
  132. if (m_sock == 0)
  133. {
  134. // Did you miss to call Create()? Did you already close the socket?
  135. ASSERT(false);
  136. return false;
  137. }
  138.  
  139. // Note: Once Close() is called, you cannot re-use the socket!
  140. // CESSocket class is neither designed to support multiple
  141. // instances not to re-use once closed connections. You must
  142. // delete the current instance and create a new one for a
  143. // re-connection or a connection to a different server.
  144.  
  145. memset(&dest_sin, 0, sizeof dest_sin);
  146. dest_sin.sin_family = AF_INET;
  147. dest_sin.sin_port = htons(nHostPort);
  148.  
  149. if (_tcschr(lpszHostAddress, '.') == 0)
  150. {
  151. #ifdef _UNICODE
  152. phe = gethostbyname(W2A(lpszHostAddress));
  153. #else
  154. phe = gethostbyname(lpszHostAddress);
  155. #endif
  156.  
  157. if (phe == NULL)
  158. {
  159. m_nLastError = WSAGetLastError();
  160. TRACE(_T("gethostbyname failed\n"));
  161. return false;
  162. } // if
  163.  
  164. memcpy((char FAR *)&(dest_sin.sin_addr), phe->h_addr, phe->h_length);
  165. } // if
  166. else
  167. {
  168. #ifdef _UNICODE
  169. address.s_addr = inet_addr(W2A(lpszHostAddress));
  170. #else
  171. address.s_addr = inet_addr(lpszHostAddress);
  172. #endif
  173.  
  174. dest_sin.sin_addr = address;
  175. }
  176.  
  177. if (connect(m_sock, (LPSOCKADDR)&dest_sin, sizeof dest_sin))
  178. {
  179. m_nLastError = WSAGetLastError();
  180. TRACE(_T("Connection to server failed.\nCheck host-id and port# !\n"));
  181. return false;
  182. }
  183.  
  184. if (WSAAsyncSelect(m_sock, *m_pWndMessageTarget, WM_LTC_WINSOCK_MSG_RECEIVED, FD_READ) > 0)
  185. {
  186. m_nLastError = WSAGetLastError();
  187. TRACE(_T("WSAAsyncSelect failed\n"));
  188. return false;
  189. } // if
  190.  
  191. TRACE(_T("Connection to server OK\n"));
  192. m_nLastError = 0;
  193. ASSERT(m_sock != 0);
  194. return true; // success
  195. }
  196.  
  197. int CESSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
  198. {
  199. if (send(m_sock, (const char*)lpBuf, nBufLen, nFlags) == SOCKET_ERROR)
  200. {
  201. m_nLastError = WSAGetLastError();
  202. return false;
  203. }
  204.  
  205. m_nLastError = 0;
  206. return true;
  207. }
  208.  
  209. int CESSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
  210. {
  211. int nBytes = 0;
  212.  
  213. if ((nBytes = recv(m_sock, (char*)lpBuf, nBufLen, nFlags)) == SOCKET_ERROR)
  214. {
  215. m_nLastError = WSAGetLastError();
  216. return false;
  217. }
  218.  
  219. m_nLastError = 0;
  220. return nBytes;
  221. }
  222.  
  223. void CESSocket::Close()
  224. {
  225. if (m_sock)
  226. {
  227. m_nLastError = 0;
  228. ASSERT(m_pWndMessageTarget);
  229.  
  230. // stop receiving messages
  231. WSAAsyncSelect(m_sock, *m_pWndMessageTarget, 0, 0);
  232.  
  233. if (closesocket(m_sock) == SOCKET_ERROR)
  234. m_nLastError = WSAGetLastError();
  235.  
  236. m_sock = 0;
  237. TRACE(_T("Socket closed\n"));
  238. }
  239. }
  240.  
  241. int CESSocket::GetLastError()
  242. {
  243. return m_nLastError;
  244. }
  245.  
  246. /////////////////////////////////////////////////////////////////////////////
  247. // CMessageTargetWnd class
  248. //
  249.  
  250. CMessageTargetWnd::CMessageTargetWnd(CESSocket *pESSocket)
  251. {
  252. m_pESSocket = pESSocket;
  253. }
  254.  
  255. LRESULT CMessageTargetWnd::OnDataReceive(WPARAM wParam, LPARAM lParam)
  256. {
  257. m_pESSocket->OnReceive(HIWORD(lParam));
  258. return 0;
  259. }
  260.  
  261. BEGIN_MESSAGE_MAP(CMessageTargetWnd, CWnd)
  262. ON_MESSAGE(WM_LTC_WINSOCK_MSG_RECEIVED, OnDataReceive)
  263. END_MESSAGE_MAP()

解决CSocket高数据传输问题的更多相关文章

  1. 解决Safari高版本浏览器中默认禁用第三方COOKIE(含demo)

    前段时间在项目里遇到了一个比较头疼的问题,就是高版本的Safari中默认会阻止第三方cookie,这使得使用Safari浏览器的用户无法按照正常的业务逻辑进行操作. 问题展现 知识点 什么是第三方co ...

  2. Android中ListView嵌套GridView的简单消息流UI(解决宽高问题)

    最近搞一个项目,需要用到类似于新浪微博的消息流,即每一项有文字.有九宫格图片,因此这就涉及到ListView或者ScrollView嵌套GridView的问题.其中GridView的高度问题在网上都很 ...

  3. Java集群--大型网站是怎样解决多用户高并发访问的

    时间过得真快,再次登录博客园来写博,才发现距离上次的写博时间已经过去了一个月了,虽然是因为自己找了实习,但这也说明自己对时间的掌控能力还是没那么的强,哈哈,看来还需不断的努力啊!(这里得特别说明一下本 ...

  4. 利用redis + lua解决抢红包高并发的问题

    抢红包的需求分析 抢红包的场景有点像秒杀,但是要比秒杀简单点.因为秒杀通常要和库存相关.而抢红包则可以允许有些红包没有被抢到,因为发红包的人不会有损失,没抢完的钱再退回给发红包的人即可.另外像小米这样 ...

  5. 解决vs-code高cpu占用率问题

    (microsoft.vscode.cpp.extension.darwin进程高cpu占用问题) 免费的vs-code现在已经成为mac/linux平台的码农新宠,毕竟从windows平台开发vir ...

  6. oracle解决导入高版本dmp报错问题:IMP-00058: ORACLE error 12547 encountered

    低版本oracle导入高版本的dmp时,导过的人都应该清楚,直接导入是会报错的,报错信息如下,其实解决这个问题很简单, 只要修改一下dmp内的版本号就可以了. 修改版本不能随便使用文本工具打开,否知会 ...

  7. 解决eclipse高版本JDK编译的项目到低版本JDK服务器上不能运行的问题

    错误提示信息:Unsupported major.minor version 52.0,意思是说,当前jdk的版本不支持更高版本jdk编译出来的class文件. 我的编译环境,eclipse使用的是j ...

  8. Redis:解决分布式高并发修改同一个Key的问题

    本篇文章是通过watch(监控)+mutil(事务)实现应用于在分布式高并发处理等相关场景.下边先通过redis-cli.exe来测试多个线程修改时,遇到问题及解决问题. 高并发下修改同一个key遇到 ...

  9. 翻屏类 h5 适配方案:解决宽高自适应难题

    表格 图片等 宽度自适应  :width:100%;  box-sizing: border-box; 基于淘宝适配方案flexible + 翻屏h5 适配方案adaptive flexible解读及 ...

随机推荐

  1. 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 ...

  2. springcloud系列13 config的客户端使用

    config客户端的使用: 也是首先要引入依赖: <dependency> <groupId>org.springframework.cloud</groupId> ...

  3. java笔试之自守数

    自守数是指一个数的平方的尾数等于该数自身的自然数.例如:25^2 = 625,76^2 = 5776,9376^2 = 87909376.请求出n以内的自守数的个数 接口说明 /*功能: 求出n以内的 ...

  4. Pascal代码自动格式化

    const WEnter=; key=; next_line:..WEnter]of string=(';','begin','else','then','repeat','do','var'); k ...

  5. Python全栈开发:协程代码实例

    协程代码1 #!/usr/bin/env python # -*- coding;utf-8 -*- # 导入协程模块 """ 协程工作原理 ""&q ...

  6. Python全栈开发:模块

    模块,用一砣代码实现了某个功能的代码集合. 参考资源:http://www.cnblogs.com/alex3714/articles/5161349.html 类似于函数式编程和面向过程编程,函数式 ...

  7. Stopwatch 计时器类

    C#_Stopwatch 类   命名空间:System.Diagnostics Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.在典型的 Stopwatc ...

  8. MongDB4.1-入门学习之下载安装配置

    下载安装配置三步走 下载,MongoDB官网下载中心 下载_.msi_安装版 安装,注意以下几个步骤: Choose Setup Type: Please Choose Custom Custom S ...

  9. Idea安装Mevn

    1.下载mevn安装包. 下载地址:http://maven.apache.org/ 点击Download 2.下面这两个选哪个都可以,取决于你用什么方式解压 3.把下载好的安装包解压到一个没有中文的 ...

  10. thinkphp 自动验证

    自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创建数据对象的时候自动进行数据验证. 大理石平台价格表 验证规则 数据验证可以进行数据类型.业务规则.安全判断等方面的验证 ...