热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

IOCP六:UDP客户端退出

实验过程:1.线程A在sockets上投递1号WSARecvFrom2.Client发送woyougexiaozhinv,kewoburenshita

实验过程:

        1.线程A在socket s上投递1号WSARecvFrom

        2.Client发送"woyougexiaozhinv,kewoburenshita"

        3.1号WSARecvFrom接收数据,创建线程B

        4.线程B投递2号WSARecvFrom,然后线程A投递3-10号WSARecvFrom

        5.线程B每隔两秒发送"nihaihaoma"

        6.Client接两次后发送"woyougexiaozhinv,kewoburenshita",然后退出


实验结果:

        1.Client最后发送的数据由2号WSARecvFrom接收

        2.线程B第三次发送数据,显示:发送成功   影响:3号WSARecvFrom以“ret=false, dwNum=0, GetLastError()=1234, 目标地址”返回

           线程B第四次发送数据,显示:发送成功   影响:4号WSARecvFrom以“ret=false, dwNum=0, GetLastError()=1234, 目标地址”返回

           线程B第五次发送数据,显示:发送成功   影响:5号WSARecvFrom以“ret=false, dwNum=0, GetLastError()=1234, 目标地址”返回

           。。。


实验结论:

        用socket s向一个不存在的地址投递WSASendTo,显示:发送成功,结果:在s上等待接收的WSARecvFrom按投递顺序以”ret=false,dwNum=0,GetLastError()=1234,ppiod->clientAddr=目标地址“四参数返回


实验结果图:



实验代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "Kernel32.lib")
#pragma comment(lib, "Mswsock.lib")

#define BUF_LEN 1024

bool flag = true;

enum OperateType
{
	OP_RECV,
	OP_SEND,
};

typedef struct PER_HANDLE_DATA
{
	SOCKET s;
	SOCKADDR_IN addr;
}PER_HANDLE_DATA, *LPPER_HANDLE_DATA;

typedef struct PER_IO_DATA
{
	OVERLAPPED overlapped;
	int no;
	char buf[BUF_LEN]; 
	int operationType;
	sockaddr clientAddr;
}PER_IO_DATA, *LPPER_IO_DATA;

typedef struct Arg
{
	SOCKET s;
	sockaddr addr;
}Arg;

SOCKET SocketInitBind()
{
	SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
	if(INVALID_SOCKET == s)
	{
		std::cout<<"create socket failed : "<overlapped), sizeof(OVERLAPPED));
	ppiod->operatiOnType= OP_SEND;
	ppiod->clientAddr = *clientAddr;
	ppiod->no = 128;
	memset(ppiod->buf, 0, BUF_LEN);
	memcpy(ppiod->buf, buf, len);

	WSABUF databuf;
	databuf.buf = ppiod->buf;
	databuf.len = len;

	DWORD dwRecv = 0;
	DWORD dwFlags = 0;
	int ret = WSASendTo(s, &databuf, 1, &dwRecv, dwFlags, clientAddr, sizeof(sockaddr), &ppiod->overlapped, NULL);
	if(SOCKET_ERROR == ret && WSA_IO_PENDING != GetLastError())
	{
		delete ppiod;
		return false;
	}

	return true;
}

bool PostRecvFrom(SOCKET s, int n)
{
	LPPER_IO_DATA ppiod = new PER_IO_DATA;

	//ZeroMemory(&(ppiod->overlapped), sizeof(OVERLAPPED));
	ZeroMemory(ppiod, sizeof(PER_IO_DATA));
	ppiod->operatiOnType= OP_RECV;
	ppiod->no = n;
	memset(ppiod->buf, 0, BUF_LEN);

	WSABUF databuf;
	databuf.buf = ppiod->buf;
	databuf.len = BUF_LEN;

	DWORD dwRecv = 0;
	DWORD dwFlags = 0;
	int len = sizeof(sockaddr);
	int ret = WSARecvFrom(s, &databuf, 1, &dwRecv, &dwFlags, &ppiod->clientAddr, &len, &ppiod->overlapped, NULL);
	if(SOCKET_ERROR == ret && WSA_IO_PENDING != GetLastError())
	{
		delete ppiod;
		return false;
	}

	return true;
}

unsigned int __stdcall Func(void *param)
{
	Arg *arg = (Arg*)param;
	SOCKET s = arg->s;
	sockaddr addr = arg->addr;

	PostRecvFrom(s, 2);

	while(1)
	{
		Sleep(2000);
		std::string str = "nihaihaoma";
		PostSendTo(s, &addr, str.c_str(), str.length());
	}

	_endthreadex(0);
	return 0;
}

unsigned int __stdcall ThreadFunc(void *arg)
{
	HANDLE hcp = (HANDLE)arg;
	if(NULL == hcp)
	{
		std::cout<<"thread arg error"<no<To:"<operationType;
		if(OP_RECV == type)
		{
			//
			std::cout<<"接收完成"<clientAddr, sizeof(sin));
			char *ip = inet_ntoa(sin.sin_addr);
			int port = sin.sin_port;
			std::cout<<"From:"<buf[dwNum] = '\0';
			std::cout<<"Receiver : "<no<<"  "<buf<s;
				arg.addr = ppiod->clientAddr;
				//测试在s等待接收时,另一线程在s上投递发送会怎样
				_beginthreadex(NULL, 0, Func, (void*)&arg, 0, NULL);
				//等待子线程成功读取参数
				Sleep(500);

				//投递3-10号接收请求
				for(int i = 3; i <11; i++)
				{
					bool ret = PostRecvFrom(pphd->s, i);
					if(false == ret)
					{
						std::cout<<"PostAccept Failed"<overlapped), sizeof(OVERLAPPED));
			ZeroMemory(ppiod->buf, BUF_LEN);
			ppiod->no = 14;
			WSABUF databuf;
			databuf.buf = ppiod->buf;
			databuf.len = BUF_LEN;

			DWORD dwRecv = 0;
			DWORD dwFlags = 0;
			int len = sizeof(sockaddr);
			WSARecvFrom(pphd->s, &databuf, 1, &dwRecv, &dwFlags, &ppiod->clientAddr, &len, &ppiod->overlapped, NULL);*/
		}
		else if(OP_SEND == type)
		{
			//
			std::cout<<"发送完成"<clientAddr, sizeof(sin));
			std::cout<<"To:"< setWorkers;
	SYSTEM_INFO si;
	GetSystemInfo(&si);
	for(int i = 0; i s = s;
	CreateIoCompletionPort((HANDLE)s, hcp, (DWORD)pphd, 0);

	//投递编号1接收请求
	bool ret = PostRecvFrom(s, 1);
	if(false == ret)
	{
		std::cout<<"PostAccept Failed"< 


客户端代码:

#include  
#include  
#include 

#pragma comment(lib, "Ws2_32.lib")

int main() 
{ 
	WSADATA ws;

	if(WSAStartup(MAKEWORD(2, 2), &ws) != 0)
		return -1;

	sockaddr_in addr; 
	int len = sizeof(addr); 
	addr.sin_family = AF_INET; 
	addr.sin_port = htons(4444);
	addr.sin_addr.s_addr = inet_addr("192.168.15.14"); 
	SOCKET s = socket(AF_INET, SOCK_DGRAM, 0); 
	
	std::string str = "woyougexiaozhinv,kewoburenshita";
	int ret = sendto(s, str.c_str(), str.length(), 0, (sockaddr*)&addr, len);
	if (SOCKET_ERROR == ret) 
	{
		std::cout<<"Data Send Fail"< 




推荐阅读
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • 本文介绍了一个视频转换软件MyVideoConverter,该软件支持将mpg转换成swf格式,支持多种格式的转换,转换速度快,还能转换成3GP格式,同时具有音频分离提取功能。欢迎使用MyVideoConverter进行视频转换和音频提取。 ... [详细]
author-avatar
shengxin11
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有