解决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解读及 ...
随机推荐
- java设计模式系列1-- 概述
准备开始写些设计模式的随笔,这是第一篇,概述主要回顾下六大原则 先用轻松和谐的语言描述下这6个原则: 单一职责 每个类甚至每个方法都只要做自己分内的事,不要背别人的锅,也就是功能要分类,代码要解耦 里 ...
- 13_springmvc拦截器应用
一.实现登录认证 1.需求: 用户请求url,拦截器进行拦截校验 如果请求的url是公开地址(无需登陆即可访问的url),让放行 如果用户session 不存在跳转到登陆页面 如果用户session存 ...
- spring AOP 编程--AspectJ注解方式 (4)
1. AOP 简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, ...
- HTML-完美解决父子元素的外边距重叠和高度塌陷问题
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- B/S架构及其运行原理
一. B/S的概念 B/S(Brower/Server,浏览器/服务器)模式又称B/S结构,是Web兴起后的一种网络结构模式.Web浏览器是客户端最主要的应用软件. 这种模式统一了客户端,将系统功能实 ...
- PAT甲级——A1066 Root of AVL Tree
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...
- Neo4j 第四篇:使用.NET驱动访问Neo4j
本文使用的IDE是Visual Studio 2015 ,驱动程序是Neo4j官方的最新版本:Neo4j.Driver,创建的类库工程(Project)要求安装 .NET Framework 4.5. ...
- https://blog.csdn.net/qq_33169863/article/details/82977791
https://blog.csdn.net/qq_33169863/article/details/82977791 ** 查看设备连接 adb devices ** 列出手机已安装的包名 adb ...
- css3之2D 转换
浏览器支持 表格中的数字表示支持该属性的第一个浏览器版本号. 紧跟在 -webkit-, -ms- 或 -moz- 前的数字为支持该前缀属性的第一个浏览器版本号. Chrome 和 Safari 要求 ...
- Activiti流程变量
流程变量在整个工作流中扮演很重要的作用 例如:请假流程中有请假天数.请假原因等一些参数都为流程变量的范围.流程变量的作用域范围是流程实例.也就是说各个流程实例的流程变量是不相互影响的. 添加流程变量 ...