网络编程之select头文件

#include "ccnet.h"
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <fcntl.h>

//连接服务器

static int
Connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
{
assert(serv_addr != NULL);

return connect(sockfd, serv_addr, addrlen);
}

//关闭服务器

int Close(int fd)

{
  return close(fd);
}

//连接服务器

// 入参数:IP, port,timeout

int CCConnectO(const char *host, int port, int *timeout, const char *name)

{
char buf[1024];
fd_set rset, wset;
struct hostent he, *p;
struct sockaddr_in sin;
socklen_t len = 0;
int sock = -1, ret = 0, err = 0, flags = 0, on = 1;
struct timeval t;

assert(host != NULL);

if (*timeout < 0){
*timeout = 0;
}
int old_timeout = *timeout;

// invalid server
if (host[0] == 0 || port == 0) {
return -1;
}

if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
LOG_WARN( "cannot create socket while connecting to %s(%s:%d)",name, host, port);
return -1;
}

bzero(&sin, sizeof(sin));
sin.sin_addr.s_addr = inet_addr(host);
if ((sin.sin_addr.s_addr) == INADDR_NONE) { /* host is not numbers-and-dots ip address */
ret = gethostbyname_r(host, &he, buf, sizeof(buf), &p, &err);
if (ret < 0) {
LOG_WARN("cannot resolve hostname while connecting to %s(%s:%d)",name, host, port);
close(sock);
return -1;
}
memcpy(&sin.sin_addr.s_addr, he.h_addr, sizeof(sin.sin_addr.s_addr));
}
sin.sin_family = AF_INET;
sin.sin_port = htons(port);

flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);

setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
ret = Connect(sock, (struct sockaddr *) &sin, sizeof(sin));
if (ret == 0) {
fcntl(sock, F_SETFL, flags);
LOG_INFO("connect to %s(%s:%d) OK",name, host, port);
return sock;
} else {
if (errno != EINPROGRESS) { /* cannot connect to the host */
LOG_WARN("fail while connecting to %s(%s:%d)",name, host, port);
close(sock);
return -1;
}

FD_ZERO(&rset);
FD_SET(sock, &rset);
wset = rset;
t.tv_sec = *timeout / 1000000, t.tv_usec = *timeout % 1000000;
ret = select(sock + 1, &rset, &wset, NULL, &t);
if (t.tv_sec * 1000000 + t.tv_usec < 10)
t.tv_sec = 0, t.tv_usec = 0;
*timeout = t.tv_sec * 1000000 + t.tv_usec;
if (ret == 0) {
LOG_WARN("timeout(%d us) while connecting to %s(%s:%d)",old_timeout, name, host, port);
close(sock);
return -1;
}

if (FD_ISSET(sock, &rset) || FD_ISSET(sock, &wset)) {
len = sizeof(err);
ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len);
if (ret < 0) {
if (err){
errno = err;
}
LOG_WARN("getsockopt fail while connecting to %s(%s:%d)", name, host, port);
close(sock);
return -1;
}
if (err) {
errno = err;
LOG_WARN("sockselect fail while connecting to %s(%s:%d)", name, host, port);
close(sock);
return -1;
}
fcntl(sock, F_SETFL, flags);
LOG_INFO("connect to %s(%s:%d) OK", name, host,port);
return sock;
} else {
LOG_WARN("select fail while connecting to %s(%s:%d)", name,host, port);
close(sock);
return -1;
}
}

return -1;
}

猜你喜欢

转载自www.cnblogs.com/cyblogs/p/11295682.html