TCP客户端非阻塞connect,EPOLL异步响应

2023-11-14

废话不多说,直接上代码
下面展示一些 内联代码片

#include <sys/types.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#include <fcntl.h>
#include <error.h>
#include <sys/epoll.h>
#include <pthread.h>

using namespace std;
  
#define PORT 9734

int g_epollfd = 0;

void *epollthread(void *arg)
{
	struct epoll_event events[100];
	int ret;
	while (true) {
		ret = epoll_wait(g_epollfd, events, sizeof(events), 1000);
		if (ret > 0) {
			for (int i=0;i<ret;i++) {
				if (events[i].events & EPOLLERR) {
					printf("EPOLLERR exists\n");
					// 通过 socket 获取具体失败原因
					int error;
					socklen_t error_len = sizeof(int);
					ret = getsockopt(events[i].data.fd, SOL_SOCKET, SO_ERROR, &error, &error_len);
					printf("getsockopt connect failed, errno: [%d] %s\n", error, strerror(error));
				} else {
					printf("connect successful!!!\n");
				}
				epoll_ctl(g_epollfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
			}
		} else if (ret == 0) {
			printf("epoll timeout\n");
		}
	}
    printf( "This is a thread\n");
	return NULL;
}

void nonblockingConnect(const char* ip, short port)
{
	int clientFD = socket(AF_INET, SOCK_STREAM, 0);
	if (clientFD == -1) {
		printf("create socket failed\n");
		return;
	}
 
    //设置非阻塞
	int flag = fcntl(clientFD, F_GETFL, 0);
	if (fcntl(clientFD, F_SETFL, flag | SOCK_NONBLOCK) == -1) {
		printf("fcntl failed\n");
		close(clientFD);
		return;
	}
 
	struct sockaddr_in srvAddr;
	memset(&srvAddr, 0, sizeof(struct sockaddr_in));
	srvAddr.sin_addr.s_addr = inet_addr(ip);
	srvAddr.sin_port = htons(port);
	srvAddr.sin_family = AF_INET;
 
    //为了处理EINTR,将connect放在循环内
    while (1) {
        int ret = connect(clientFD, (sockaddr*)&srvAddr, sizeof(struct sockaddr_in));
        if (ret == 0) {
            cout << "connect successfully" << endl;
            return;
        } else if (ret == -1) {
			// 非阻塞 connect 一般都是返回 -1 , errno 设置为 EINPROGRESS
            if (errno == EINTR) {
                cout << "signal interrupt" << endl;
                continue;
            } else if (errno != EINPROGRESS) {
                cout << "can not connect to server, errno: " << errno << endl;
                close(clientFD);
                return;
            } else {
				struct epoll_event ev;
				ev.events = EPOLLOUT | EPOLLERR;
				ev.data.fd = clientFD;
				epoll_ctl(g_epollfd, EPOLL_CTL_ADD, clientFD, &ev);
                return;
            }
        }
    }
	return;
}

int main()
{
	g_epollfd = epoll_create(10);
    pthread_t thread_one;
    int ret;
    ret = pthread_create(&thread_one, NULL, epollthread, NULL);  
    if (ret != 0) {
        printf( "Create thread error!\n");  
        return -1;
    }

	nonblockingConnect("127.0.0.1", PORT);

	printf("This is the main process.\n");
    pthread_join(thread_one, NULL);
	return 0;  
}  

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

TCP客户端非阻塞connect,EPOLL异步响应 的相关文章

  • dup2() 和 exec()

    include
  • 如果两个线程同时访问同一个 bool 变量会发生什么?

    我有一个跨平台 C 程序 其中使用 boost 库创建异步计时器 我有一个全局变量 bool receivedInput false 一个线程等待并处理输入 string argStr while 1 getline cin argStr
  • binary_log_types.h:没有这样的文件或目录

    我正在编译一个小型 mysql C 项目并且 遇到以下错误 C Program Files x86 MySQL MySQL Server 5 7 include mysql com h 22 30 fatal error binary lo
  • C# 并行与并行线程代码性能

    我一直在测试 System Threading Parallel 与线程的性能 我很惊讶地发现并行比线程花费更长的时间来完成任务 我确信这是由于我对并行的了解有限 我刚刚开始阅读 我想我会分享一些片段 如果有人可以向我指出并行代码比线程代码
  • 修剪 UIImage 边框

    这是我想要修剪的图像的示例 我想去掉图像周围的边框 在本例中是顶部和底部的黑条 我在Github上找到了一个库 CKImageAdditions https github com cmkilger CKImageAdditions 但是它似
  • 如何删除实体框架6中的多对多关系

    如果将项目连接为多对多关系 则从数据库中删除项目时会出现问题 我的数据库看起来像 Project lt JobInProject gt Job ProjectID JobInProjectID JobID ProjectID JobID 主
  • EF Core 一对多关系列表返回 null

    我正在尝试学习如何在 EF Core 中正确利用 DbContext 我有一个团队课程 public class Team public int ID get set public string Name get set public bo
  • 三种 System.Drawing 方法表现出缓慢的绘制或闪烁:解决方案?或其他选择?

    我正在通过 System Drawing 进行一些绘图 但遇到了一些问题 我将数据保存在队列中 并将该数据绘制 绘制 到三个图片框中 此方法填充图片框 然后滚动图形 所以不要在以前的绘图上绘制 并且逐渐看起来更混乱 我找到了两种绘制图表的解
  • 为什么 httpRuntime targetFramework="4.5" 禁止抓取 .ASPXAUTH cookie?

    当我的 web config 具有以下 httpRuntime 时 我的控制器无法获取 cookie ASPXAUTH 它似乎能够获取任何其他 cookie 无论带或不带句点前缀 如果我删除下面的行 它就可以正常工作
  • C++:LPWSTR 在 cout 中打印为地址

    我有一个类型变量LPTSTR 我打印到std cout with lt lt 在 ANSI 系统中 不知道它是在哪里确定的 它工作得很好 它打印了字符串 现在 在 Unicode 系统中 我得到的是十六进制地址而不是字符串 那么 为什么LP
  • 从视图模型调用方法的命令

    好吧 我倾向于避免使用命令 因为它们总是让我感到困惑 但我正在进行一个新项目 并且正在尝试正确构建它 并且在我看来没有任何代码隐藏 基本上我现在想做的就是连接一个按钮来触发一个命令 在我的视图模型上执行一些操作 但不知何故 如此简单的事情仍
  • 我可以对(非成员)函数使用部分模板特化吗?

    我试图在 非成员 函数上使用部分模板专业化 但我在语法上遇到了问题 我在 StackOverflow 中搜索了其他部分模板专业化问题 但这些问题涉及类或成员函数模板的部分专业化 作为起点 我有 struct RGBA RGBA uint8
  • 生成范围 [min,max] 内的随机数 [重复]

    这个问题在这里已经有答案了 我正在使用 C 生成范围 min max 内的整数随机数 我在用 int random int int min int max return min rand max min 但我认为上面的代码适用于范围 min
  • 如何在asp.net core 6中注入IConfiguration

    web api 应用程序中不再有 Startup cs 我们以前可以注入IConfiguration进入那个Startup class public class Startup public Startup IConfiguration c
  • #define 内存地址声明

    这个 define 语句有什么作用 它用于定义内存地址 但我不明白 uint32 t 部分 define GPxDAT uint32 t 0x6FC0 通常用于访问映射到地址空间的硬件寄存器 或者一些特定的内存地址 硬件寄存器应定义为vol
  • C++ 联合数组和变量?

    在C 中没有办法做这样的事情吗 union Scalar x y Scalar v 2 Where x v 0 and y v 1 既然您使用的是 C 而不是 C 并且它们具有相同的类型 为什么不直接将 x 设为对 v 0 的引用 将 y
  • 如何创建和使用类箭头运算符? [复制]

    这个问题在这里已经有答案了 因此 在到处研究之后 我似乎找不到如何创建类箭头运算符 即 class Someclass operator gt 我只需要知道如何使用它并正确使用它 它的输入是什么 它返回什么 我如何正确地声明 原型化它 运算
  • C# 3.0 中自动属性和公共字段的区别

    我无法理解为什么 C 3 0 中存在自动实现的属性语言功能 当你说的时候有什么区别 public string FirstName than public string FirstName get set 因为它们在生成的 IL 代码 和机
  • Linux shell 标题大小写

    我正在编写一个 shell 脚本并有一个如下所示的变量 something that is hyphenated 我需要在脚本中的各个点使用它 如下所示 something that is hyphenated somethingthati
  • 如何使用 Ioc Unity 注入依赖属性

    我有以下课程 public interface IServiceA string MethodA1 public interface IServiceB string MethodB1 public class ServiceA IServ

随机推荐