int create_tcp_client(const char *src_addr, const short src_port, const char *dst_addr,
const short dst_port, const bool non_block, const int timeout)
{
int sockfd;
struct sockaddr_in src_in;
struct sockaddr_in dst_in;
if(!dst_addr && 0 == dst_port) {
return -1;
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0) {
return -1;
}
memset(&src_in, 0, sizeof(src_in));
src_in.sin_family = AF_INET;
src_in.sin_port = htons(src_port);
src_in.sin_addr.s_addr = src_addr ? inet_addr(src_addr) : INADDR_ANY;
if(bind(sockfd, (struct sockaddr *)&src_in, sizeof(struct sockaddr_in))) {
close(sockfd);
return -1;
}
if(!non_block) {
int flag;
/* set the socket to non-blocking */
flag = fcntl(sockfd, F_GETFL, 0);
if(-1 == fcntl(sockfd, F_SETFL, flag|O_NONBLOCK)) {
close(sockfd);
return -1;
}
}
memset(&dst_in, 0, sizeof(dst_in));
dst_in.sin_family = AF_INET;
dst_in.sin_port = htons(dst_port);
dst_in.sin_addr.s_addr = inet_addr(dst_addr);
if(connect(sockfd, (struct sockaddr *)&dst_in, sizeof(struct sockaddr_in))) {
if(!non_block && EINPROGRESS == errno) {
fd_set rfds;
fd_set wfds;
struct timeval tv;
int valopt = 0;
socklen_t valopt_len = sizeof(valopt);
FD_ZERO(&rfds);
FD_SET(sockfd, &rfds);
FD_ZERO(&wfds);
FD_SET(sockfd, &wfds);
tv.tv_sec = timeout;
tv.tv_usec = 0;
if(select(sockfd+1, &rfds, &wfds, NULL, &tv) <= 0) {
close(sockfd);
return -1;
}
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&valopt, &valopt_len) < 0) {
close(sockfd);
return -1;
}
if(valopt) {
close(sockfd);
return -1;
}
}
}
return sockfd;
}
tcp socket实例
最新推荐文章于 2021-03-10 20:32:06 发布