异步Windows Socket包装,包括TCP与UDP,可处理粘包

2023-10-27

 
头文件
struct IPAddress
{
	union {
		struct IPV4Address
		{
			ULONG host;
			USHORT port;
		}address;
		UINT64 _64;
	};

	static IPAddress Zero;

	ULONG& GetHost(){return address.host;}
	USHORT& GetPort(){return address.port;}
	ULONG GetHost()const{return address.host;}
	USHORT GetPort()const{return address.port;}
	string ToString()
	{
		in_addr addr;
		addr.S_un.S_addr = address.host;
		stringstream ss;
		ss << inet_ntoa(addr) << ":" << address.port;
		return ss.str();
	}

	IPAddress(ULONG _host = 0, USHORT _port = 0)
	{
		_64 = 0;
		address.host = _host;
		address.port = _port;
	}

	bool operator < (const IPAddress& _right) const
	{
		return _64 < _right._64;
	}

	bool operator != (const IPAddress& _right) const
	{
		return _64 != _right._64;
	}

	bool operator == (const IPAddress& _right) const
	{
		return _64 == _right._64;
	}
};

class Socket
{
public:

	Socket(int proto = SOCK_STREAM);
	Socket(SOCKET s);
	virtual ~Socket();

	u_long ReceiveLen();

	void Close();

protected:
	friend class SocketSelect;
	SOCKET s_;

	int* refCounter_;
	static int  nofSockets_;

	static void Start();
	static void End();
};

class TcpClient : public Socket
{
protected:
	friend class TcpServer;
	bool connected;

	TcpClient();
	TcpClient(SOCKET s);
public:
	int SendBytes(const std::string&);
	int Send(void* buf, int len);
	int Receive(char* buf, int len);
	bool IsConnected(){return connected;}
	string ReceiveBytes();
	TcpClient(const TcpClient&);
	TcpClient& operator=(TcpClient&);
	TcpClient(const std::string& host, int port);
	TcpClient(unsigned long host, int port);
};

class UdpSocket : public Socket
{
public:
	UdpSocket(unsigned long host, int port);
	int SendBytes(const std::string&, unsigned long host, int port);
	int Send(void* buf, int len, unsigned long host, int port);
	int Send(void* buf, int len, const IPAddress& addr);
	int Receive(char* buf, int len, unsigned long& host, int& port);
	int ReadEventSelect(HANDLE _event);
};

class SocketSelect
{
	static TIMEVAL ms_tval;
	fd_set fds_;
	Socket* sock_;
public:
	SocketSelect(Socket * sock);

	bool Readable();
	bool Writeable();
};

class TcpServer : public Socket
{
	auto_ptr<SocketSelect> select;
	int Init(int port, int connections);
	
public:
	unsigned short listenPort;
	TcpServer(int port, int connections);

	TcpClient* Accept(u_long& host, USHORT& port);
};

class TcpPacketSeparator
{
	int cur_;
	int len_;
	char* data_;
public:
	TcpPacketSeparator(int maxdatalen)
	{
		len_ = maxdatalen;
		data_ = new char[maxdatalen];
		cur_ = 0;
	}

	~TcpPacketSeparator()
	{
		delete data_;
	}

	bool Process(TcpClient* s)
	{
		u_long len = 0;
		int recv_len_ = 0;

		if( cur_ >= 4 && cur_ >= *(unsigned short*)data_ )
		{
			return true;
		}

		while( (recv_len_ = s->Receive(data_ + cur_, len_ - cur_) ) > 0 )
		{
			cur_ += recv_len_;

			if( cur_ >= *(unsigned short*)data_ )
			{
				return true;
			}
		}
		
		if( recv_len_ == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK )
		{
			s->Close();
			return false;
		}

		return false;
	}

	char* GetDataPtr()
	{
		return data_;
	}

	void Done()
	{
		u_short pklen_ = *(unsigned short*)data_;
		if( cur_ > pklen_ )
		{
			memmove_s(data_, len_, data_ + pklen_, cur_ - pklen_);
			cur_ -= pklen_;
		}
		else
		{
			cur_ = 0;
		}
	}
};
CPP
#include <iostream>
using namespace std;

int Socket::nofSockets_= 0;
IPAddress IPAddress::Zero;

void Socket::Start()
{
	if (!nofSockets_)
	{
		WSADATA info;
		if (WSAStartup(MAKEWORD(2,0), &info))
		{
			throw "Could not start WSA";
		}
	}
	++nofSockets_;
}

void Socket::End()
{
	WSACleanup();
}

Socket::Socket(int proto) : s_(0)
{
	Start();
	// UDP: use SOCK_DGRAM instead of SOCK_STREAM
	s_ = socket(AF_INET,proto,proto==SOCK_DGRAM?IPPROTO_UDP:0);

	if (s_ == INVALID_SOCKET)
	{
		throw "INVALID_SOCKET";
	}

	refCounter_ = new int(1);
}

Socket::Socket(SOCKET s)
{
	Start();
	s_ = s;
	refCounter_ = new int(1);
}

Socket::~Socket()
{
	if (! --(*refCounter_))
	{
		Close();
		delete refCounter_;
	}

	--nofSockets_;
	if (!nofSockets_) End();
}

void Socket::Close()
{
	closesocket(s_);
}

u_long Socket::ReceiveLen()
{
	u_long arg = 0;
	if (ioctlsocket(s_, FIONREAD, &arg) != 0)
		return 0;

	return arg;
}

TcpClient::TcpClient() : Socket(SOCK_STREAM)
{
}

TcpClient::TcpClient(const TcpClient& o)
{
	Start();
	refCounter_=o.refCounter_;
	(*refCounter_)++;
	s_         =o.s_;
	nofSockets_++;
}

TcpClient& TcpClient::operator=(TcpClient& o)
{
	refCounter_=o.refCounter_;
	(*refCounter_)++;
	s_         =o.s_;
	nofSockets_++;

	return *this;
}

int TcpClient::Receive(char* buf, int len)
{
	return recv (s_, buf, len, 0);
}

std::string TcpClient::ReceiveBytes()
{
	std::string ret;
	char buf[1024];

	while (1)
	{
		u_long arg = 0;
		if (ioctlsocket(s_, FIONREAD, &arg) != 0)
			break;

		if (arg == 0)
			break;

		if (arg > 1024) arg = 1024;

		int rv = recv (s_, buf, arg, 0);
		if (rv <= 0) break;

		std::string t;

		t.assign (buf, rv);
		ret += t;
	}

	return ret;
}

int TcpClient::SendBytes(const std::string& s)
{
	return send(s_,s.c_str(),(int)s.length(),0);
}

int TcpClient::Send(void* buf, int len)
{
	return send(s_,(const char*)buf,len,0);
}

TcpClient::TcpClient(const std::string& host, int port) : connected(false)
{
	hostent *he;
	if ((he = gethostbyname(host.c_str())) == 0)
	{
		connected = false;
	}

	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr = *((in_addr *)he->h_addr);
	memset(&(addr.sin_zero), 0, 8); 

	if (::connect(s_, (sockaddr *) &addr, sizeof(sockaddr)))
	{
		connected = false;
	}
	else
	{
		connected = true;
	}

	u_long arg = 1;
	int ret = ioctlsocket(s_, FIONBIO, &arg);
}

TcpClient::TcpClient(unsigned long host, int port) : connected(false)
{
	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.S_un.S_addr = host;
	memset(&(addr.sin_zero), 0, 8);

	if (::connect(s_, (sockaddr *) &addr, sizeof(sockaddr)))
	{
		connected = false;
	}
	else
	{
		connected = true;
	}

	u_long arg = 1;
	int ret = ioctlsocket(s_, FIONBIO, &arg);
}

TcpClient::TcpClient(SOCKET s):Socket(s)
{
}

// 用来处理10054 UDP错误
// MS Transport Provider IOCTL to control
// reporting PORT_UNREACHABLE messages
// on UDP sockets via recv/WSARecv/etc.
// Path TRUE in input buffer to enable (default if supported),
// FALSE to disable.
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
UdpSocket::UdpSocket(unsigned long host, int port):Socket(SOCK_DGRAM)
{
	BOOL bNewBehavior = FALSE;
	DWORD dwBytesReturned = 0;
	// 用来处理10054 UDP错误
	//WSAIoctl(s_, SIO_UDP_CONNRESET, &bNewBehavior, sizeof bNewBehavior, NULL, 0, &dwBytesReturned, NULL, NULL);

	sockaddr_in sa;

	memset(&sa, 0, sizeof(sa));
	
	if( host == 0 )
	{
		char name[128];
		gethostname(name, 128);
		hostent *pHost = gethostbyname(name);
		if( pHost )
			host = **(DWORD**)(pHost-> h_addr_list);
	}

	sa.sin_family = PF_INET;
	sa.sin_addr.S_un.S_addr = host;
	sa.sin_port = htons(port);

	while(true)
	{
		if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR)
		{
			sa.sin_port = htons(port++);
			if( port > 60000 )
			{
				closesocket(s_);
				break;
			}
			continue;
		}
		
		u_long arg = 1;
		//int ret = ioctlsocket(s_, FIONBIO, &arg);

		break;
	}
}

int UdpSocket::SendBytes(const std::string& buffer, unsigned long host, int port)
{
	sockaddr_in destaddr;
	destaddr.sin_family = AF_INET;
	destaddr.sin_port = htons(port);
	destaddr.sin_addr.s_addr = host;

	return sendto(s_, buffer.c_str(), int(buffer.length()), 0, (SOCKADDR *) &destaddr, sizeof(destaddr));
}

int UdpSocket::Send(void* buf, int len, unsigned long host, int port)
{
	//return 0;
	sockaddr_in destaddr;
	destaddr.sin_family = AF_INET;
	destaddr.sin_port = htons(port);
	destaddr.sin_addr.s_addr = host;

	return sendto(s_, (char*)buf, len, 0, (SOCKADDR *) &destaddr, sizeof(destaddr));
}

int UdpSocket::Send(void* buf, int len, const IPAddress& addr)
{
	return Send(buf, len, addr.GetHost(), addr.GetPort());
}

int UdpSocket::Receive(char* buf, int len, unsigned long& host, int& port)
{
	sockaddr_in senderaddr;
	int destlen = sizeof(senderaddr);
	int ret = recvfrom(s_, buf, len, 0, (SOCKADDR *) &senderaddr, &destlen);
	host = senderaddr.sin_addr.s_addr;
	port = (int)ntohs(senderaddr.sin_port);
	return ret;
}

int UdpSocket::ReadEventSelect(HANDLE _event)
{
	return WSAEventSelect(s_, _event, FD_READ);
}

TcpServer::TcpServer(int port, int connections):listenPort(port)
{
	while( 0 != Init(listenPort, connections) )
	{
		listenPort++;
		if( listenPort > 60000 )
		{
			closesocket(s_);
			return;;
		}
	}
	select.reset(new SocketSelect(this));
}

int TcpServer::Init(int port, int connections)
{
	sockaddr_in sa;

	memset(&sa, 0, sizeof(sa));

	sa.sin_family = PF_INET;             
	sa.sin_port = htons(port);

	if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR)
	{
		return WSAGetLastError();
	}
	
	u_long arg = 1;
	int ret = ioctlsocket(s_, FIONBIO, &arg);

	listen(s_, connections);
	return 0;
}

TcpClient* TcpServer::Accept(u_long& host, USHORT& port)
{
	sockaddr_in sa;
	memset(&sa, 0, sizeof(sa));
	int destlen = sizeof(sa);

	SOCKET new_sock = accept(s_, (sockaddr *)&sa, &destlen);
	if (new_sock == INVALID_SOCKET)
	{
		int rc = WSAGetLastError();
		if(rc==WSAEWOULDBLOCK)
		{
			return 0; // non-blocking call, no request pending
		}
		else
		{
			return 0;
		}
	}
	
	u_long arg = 1;
	int ret = ioctlsocket(s_, FIONBIO, &arg);

	host = sa.sin_addr.S_un.S_addr;
	port = ntohs(sa.sin_port);

	TcpClient* r = new TcpClient(new_sock);
	return r;
}

TIMEVAL SocketSelect::ms_tval = {0, 1};

SocketSelect::SocketSelect(Socket * sock):sock_(sock)
{
}

bool SocketSelect::Readable()
{
	FD_ZERO(&fds_);
	FD_SET(const_cast<Socket*>(sock_)->s_,&fds_);

	if (select (0, &fds_, (fd_set*) 0, (fd_set*) 0, &ms_tval) == SOCKET_ERROR) 
		return true;

	if (FD_ISSET(sock_->s_,&fds_)) return true;
	return false;
}

bool SocketSelect::Writeable()
{
	FD_ZERO(&fds_);
	FD_SET(const_cast<Socket*>(sock_)->s_,&fds_);

	if (select (0, (fd_set*) 0, &fds_, (fd_set*) 0, &ms_tval) == SOCKET_ERROR) 
		return true;

	if (FD_ISSET(sock_->s_,&fds_)) return true;
	return false;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

异步Windows Socket包装,包括TCP与UDP,可处理粘包 的相关文章

  • “此应用程序已请求运行时以异常方式终止它”的原因是什么?

    Visual C 运行时抛出一个常见错误 此应用程序已请求运行时以异常方式终止它 请联系应用程序的支持团队以获取更多信息 该错误消息实际上是什么意思mean 让我用一个比喻来准确地解释我的问题 如果我看到一条消息 异常 访问冲突 0xc00
  • 将文件夹中的所有文件及其所有子文件夹移动到一个大文件夹中 - windows xp

    我有一个文件夹 c downloads ffme 里面有很多子文件夹 每个子文件夹中都有不同数量的文件 我想将所有这些单独的文件合并到一个大文件夹中 同时将它们从子文件夹中删除 我希望最终得到一个包含大量文件的文件夹 但没有子文件夹 我怎样
  • 从 Python 下载/安装 Windows 更新

    我正在编写一个脚本来自动安装 Windows 更新 我可以将其部署在多台计算机上 这样我就不必担心手动更新它们 我想用 Python 编写这个 但找不到任何关于如何完成此操作的信息 我需要知道如何搜索更新 下载更新并从 python 脚本安
  • 在运行时,我如何判断我是否在 WinXP+ 上? win32

    我正在进行一些 win32 字符串 API 调用 并假设字符串以宽字符串形式出现 这在 XP 和更高版本上有效 我该如何断言这一点 这是运行时检查还是编译时检查 我做错了吗 这是一个例子 typedef std basic string
  • 在Windows 7上安装curl后缺少libcurl-4.dll

    按照这个人的安装curl后指示 https stackoverflow com a 28757477 1186038 除了第 2 步 已安装Win64 OpenSSL v1 0 1u 轻型相反 因为下载页面中缺少版本 k http slpr
  • 导致崩溃转储的 Java 错误的解决方法

    我开发的一个程序偶尔会由于这个错误而导致 JVM 崩溃 http bugs java com bugdatabase view bug do bug id 8029516 http bugs java com bugdatabase vie
  • Windows批处理文件:将结构转换为单行字符串

    我需要将这个艰巨的任务作为批处理文件来完成 这对于 C 来说不是最困难的 但在 DOS 中是一个地狱 至少对我来说 我需要将结构转换为单个 var 字符串 才能在我的程序中再次将它们转换为该结构 别担心回归 一切都已经完成了 该结构的大小会
  • 如何使用Python在Django for Windows中激活虚拟环境?

    我被告知要在 Django for Windows 中激活虚拟环境 我应该尝试 environment path Scripts activate 但是当我输入该命令时 cmd 返回此错误 该系统找不到指定的路径 我通过输入以下命令创建了虚
  • conio.h 不包含 textcolor()?

    我一直在考虑在我用 C 编写的 DOS 程序中使用颜色 有人告诉我conio h有textcolor 函数 但是当我在代码中使用它时 编译器 链接器会向我抛出错误 说我对该函数有未定义的引用 Does conio h真的有这个功能还是有人告
  • 仅在单个端口 8080 上转发到本地主机(Windows)可能吗? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我知道如何在 Windows 上使用 xampp 设置本地网络服务器 我在主机文件 c windows system32 drivers etc ho
  • 如何验证文件名称在 Windows 中是否有效?

    是否有一个 Windows API 函数可以将字符串值传递给该函数 该函数将返回一个指示文件名是否有效的值 我需要验证文件名是否有效 并且我正在寻找一种简单的方法来完成此操作 而无需重新发明轮子 我正在直接使用 C 但针对的是 Win32
  • Git difftool 未启动外部 DiffMerge 程序

    我一直遵循 戴夫的博客条目 http www davesquared net 2009 05 setting up git difftool on windows html 链接在此answer https stackoverflow co
  • Windows 上的 ffmpeg-android ndk

    我正在尝试编译 bash 文件 带有 android ndk 的 ffmpeg 我收到如下错误 arm linux androideabi gcc 无法创建可执行文件 C 编译器测试失败 Makefile 2 config mak 没有这样
  • 如何在 Windows 下向 .sh 脚本传递参数?

    我正在尝试在 Windows 下执行 sh 脚本 我安装了 Git 它允许我执行 sh 文件 但是 如果不使用 sh 作为执行前缀 我似乎无法传递任何参数 我的 sh 文件 echo Test 1 如果我用以下命令执行它 gt sh tes
  • Windows 8 Metro 应用程序(网格应用程序)过渡时出现黑色闪烁

    我正在基于网格应用程序模板构建 Windows 8 Metro 应用程序 一切都很顺利 直到我尝试更改应用程序的主题和背景 我将图像背景应用于所有 3 个 XAML 页面的网格 另外 我在应用程序包清单中将主题更改为 Light 但它没有执
  • 什么是 SO_SNDBUF 和 SO_RCVBUF

    你能解释一下到底是什么吗SO SNDBUF and SO RCVBUF选项 好的 出于某种原因 操作系统缓冲传出 传入数据 但我想澄清这个主题 他们的角色 通 常 是什么 它们是每个套接字的缓冲区吗 传输层的缓冲区 例如 TCP 缓冲区 和
  • 在 64 位 Windows 上运行 32 位可执行文件时出现问题

    如果允许的话 我会添加 500 个我自己的代表作为赏金 我在用着wkhtml转pdf http wkhtmltopdf org 将 HTML 网页转换为 PDF 这在我的 32 位开发服务器上完美运行 不幸的是 我无法运送我的机器 p 但是
  • Nexus 7 (2013) 和 Win 7 64 - 尽管检查了许多论坛和在线资源,仍无法安装 USB 驱动程序

    我正在尝试设置 Nexus 7 2013 进行调试 但我在安装 USB 驱动程序的步骤中陷入困境 到目前为止 这是我尝试过的 采取的步骤 在 Nexus 7 2013 上打开调试模式 连接设备至 PC 下载 Google USB 驱动程序于
  • Tkinter - 浮动窗口 - 调整大小

    灵感来自this https stackoverflow com a 22424245 13629335问题 我想为我的根窗口编写自己的调整大小函数 但我刚刚注意到我的代码显示了一些性能问题 如果你快速调整它的大小 你会发现窗口没有像我希望
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo

随机推荐

  • linux重启网卡的命令行,linux系统重启网卡命令

    关于win10系统开机总是要禁用重启网卡才能联网如何解决就为大家介绍到这边了 有遇到同样情况的用户们可以采取上面的方法步骤来解决 问题2已知win7下不需要删除qos协议 在跑无盘模式下以前最好不要安装厂商网卡驱动或修改win7网络协议种类
  • iOS_适配 iOS16 转屏

    iOS 适配 iOS16 转屏 问题1 iOS 16 屏幕旋转报错 Orientation BUG IN CLIENT OF UIKIT Setting UIDevice orientation is not supported Pleas
  • python 列表中最长字符串,Python选择列表中最长字符串的最有效方法?

    I have a list of variable length and am trying to find a way to test if the list item currently being evaluated is the l
  • 大数据量定时超时-精确到秒

    一 背景 开发过程中或多或少会遇到某些场景 要求数据在规定的时间内如果没处理就要失效掉 如 用户下单 订单在30分钟内没支付就要自动取消 防止长时间占用库存等 面对这种情况我们来扒拉一下 系统启一个定时任务 定时扫库 取出超过30分钟的数据
  • 蓝桥杯2020年第十一届国赛真题-重复字符串

    说在前面 本题的标程是存在问题的 下面会分析标程与正确程序 题目 题目连接 题解 思维吧 整体思路 将字符串分割成k段 假设每段m个字符 我们统计每段相同位置的每种字符出现的次数 每段都统计上后 每个位置 0 m 1 都取出现次数最多的字符
  • 排序算法-选择排序

    文章目录 关于选择排序 选择排序设计思路 选择排序实现代码 关于选择排序 选择排序是排序算法中最简单的一种 它的工作过程是基于多次重复性的遍历当前数字集合得出并最大值 最小值并剔除的行为来进行的 选择排序设计思路 关于选择排序设计思路 非递
  • wx.getLocation接口申请失败 失败原因总结 解决思路 解决方案 案例

    wx getLocation接口申请失败 失败原因总结 解决思路 解决方案 案例 目录 wx getLocation接口申请失败 失败原因总结 解决思路 解决方案 案例 一 添加类目和设置主营类目 基本设置 服务类目 二 在开发管理 接口设
  • python爬取京东商品列表信息

    爬遍电商之京东篇 目标是爬取指定商品的商品列表信息 包括商品名 价格 评论数 店铺名 打开京东页面 随便搜一个笔记本 F12打开NetWork开始抓包 翻个3页 遇到断点就按F8执行 然后看到第一个返回内容的ajax请求 是返回了第1页的后
  • Python Unittest简明教程

    1 概述 单元测试是一种软件测试方法 通过来测试源代码中的各个单元 例如类 方法等 以确定它们是否符合要求 直观上来说 可以将单元视为最小的可测试部分 单元测试是程序员在开发过程中创建的短代码片段 它构成了组件测试的基础 2 unittes
  • IC项目小任务(ncsim/tcl脚本实现)。提取SRAM实例层次结构、对应module名称、对应位宽深度

    层次结构对应的例化名和spec sram里面的模块名一一对应 ncsim终端命令里 可以使用脚本实现 set scope list find scope tbench U top recursive all internals wires
  • 回形数的思路,规律及输出代码(数组章节即学即练)

    整体思路图 规律解释及代码 package shuzu import java util Scanner public class shuzu public static void main String args 回形数整体思路 步骤 1
  • 如何修改容docker容器的shmsize共享内存大小

    很多同学在docker里面运行程序时会得到这样的错误 RuntimeError DataLoader worker pid 6209 is killed by signal Bus error It is possible that dat
  • uniapp引入uview组件库

    uniapp引入uview组件库 引言 引入方法 引言 新学期又双叒开始了 一看学校的教程要求少不了得做个小的demo为最后的课程设计做准备的 通常这个课程设计是比较花时间的 所以这次决定提前准备 毕竟都大三了 估计下学期就得去图书馆 坐牢
  • QT中的文件操作

    QT中的文件操作基于QFile类 1 打开文件 open bool open File fh QIODevice OpenMode mode QFileDevice FileHandleFlags handleflags DontClose
  • PCB相关知识-焊盘Pad

    文章目录 焊盘Pad 常规焊盘Reguar Pad 热焊盘Thermal Pad 隔离焊盘Anti Pad 总结 焊盘Pad 焊盘就是元器件封装中的引脚 在实际应用中使用焊锡将电阻 电容 电感 芯片等元器件的引脚和焊盘Pad连接在一起 电气
  • DeepSort算法简介

    SORT算法 SORT Simple Online and Realtime Tracking 算法是一种目标追踪算法 其简单有效 基于IOU来匹配 并且融入了卡尔曼滤波和匈牙利算法来降低ID Switch 可以说 追踪算法的目标只有两个
  • 内核态do_gettimeofday()、用户态gettimeofday()获取指令执行时间

    背景 芯片开发阶段 有个硬件有个配置一直无法生效 后面发现是软件写入使能还未能生效 硬件就开始配置了 导致不成功 加个延时就可解决 只是知道应该在纳秒级别 但具体十位还是百位级别 不太清楚了 所以就让我搞个代码测试下 写入一次寄存器需要的时
  • 瞎写

    1 小时候爱情就是一切 长大了 爱情变成可有可无的东西 就如同饭菜 有它 饭更香 没有它 饭还是饭 饿了也得吃下去 2 我想滚蛋 在这儿真的是学无所学 我都想自己开始创业 真的对不起老板给的这份工资 整天无所事事 3 不是合适不合适的问题
  • C语言图书馆管理系统

    C语言图书馆管理系统 全部代码如下 include
  • 异步Windows Socket包装,包括TCP与UDP,可处理粘包

    头文件 struct IPAddress union struct IPV4Address ULONG host USHORT port address UINT64 64 static IPAddress Zero ULONG GetHo