废话不多说,直接上代码
下面展示一些 内联代码片
。
#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;
}