代码拉取完成,页面将自动刷新
// netlib_base.c
#include "netlib_base.h"
#include <stdio.h>
#include <time.h>
#include <assert.h>
#ifdef _WIN32
BOOL ks_net_environ_init(int max_fd_num) {
WSADATA wsa_data;
assert( max_fd_num > 0 );
// need use windows socket 2.0
//
return WSAStartup(MAKEWORD(2,0),&wsa_data)==0;
}
void ks_net_environ_final(void) {
WSACleanup();
}
int ks_sock_set_blocking(KSSockFD fd, BOOL block) {
u_long flag = block ? 0L : 1L;
return ioctlsocket(fd, FIONBIO, &flag);
}
#else//LINUX
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/resource.h>
#include <netinet/tcp.h>
BOOL ks_net_environ_init(int max_fd_num) {
struct rlimit rt;
memset(&rt, 0, sizeof(rt));
if( getrlimit(RLIMIT_NOFILE, &rt) != 0 ) {
perror("getrlimit failed!");
return FALSE;
}
if( rt.rlim_cur < (size_t)max_fd_num ) {
perror("need more fd size, try 'ulimit -n' modify it!");
return FALSE;
}
signal(SIGPIPE, SIG_IGN);
return TRUE;
}
void ks_net_environ_final(void) {
}
int ks_sock_set_blocking(KSSockFD fd, BOOL block) {
int flags = fcntl(fd, F_GETFL, 0);
if( flags < 0 )
return -1;
flags = block ? (flags&(~O_NONBLOCK)) : (flags|O_NONBLOCK);
return fcntl(fd, F_SETFL, flags);
}
#endif//_WIN32
int ks_sock_set_tcp_nodelay(KSSockFD fd, BOOL nodelay) {
int nodelay_opt = nodelay ? 1 : 0;
return ks_sock_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay_opt, sizeof(nodelay_opt));
}
int ks_sock_set_linger(KSSockFD fd, BOOL on, uint16_t time_second) {
struct linger linger_opt = { on, time_second };
return ks_sock_setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt));
}
int ks_sock_set_sndbuf(KSSockFD fd, int len) {
return ks_sock_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &len, sizeof(len));
}
int ks_sock_set_rcvbuf(KSSockFD fd, int len) {
return ks_sock_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
}
int ks_sock_getsockname(struct sockaddr* addr, KSSockFD fd) {
socklen_t len = sizeof(struct sockaddr);
return fd==INVALID_SOCKET ? -1 : getsockname(fd, addr, &len);
}
int ks_sock_getpeername(struct sockaddr* addr, KSSockFD fd) {
socklen_t len = sizeof(struct sockaddr);
return fd==INVALID_SOCKET ? -1 : getpeername(fd, addr, &len);
}
BOOL ks_net_address_parse(char saddr[32], const struct sockaddr* addr) {
if( !addr )
return FALSE;
// IPv4
if( addr->sa_family==AF_INET ) {
struct sockaddr_in* ipv4 = (struct sockaddr_in*)addr;
uint32_t ip = ntohl(ipv4->sin_addr.s_addr);
if( ip==INADDR_ANY )
sprintf(saddr, "%u", ntohs(ipv4->sin_port));
else
sprintf(saddr, "%u.%u.%u.%u:%u", (ip>>24)&0xFF, (ip>>16)&0xFF, (ip>>8)&0xFF, ip&0xFF, ntohs(ipv4->sin_port));
return TRUE;
}
return FALSE;
}
BOOL ks_net_address_make_ip_port(struct sockaddr* addr, const char* ip, uint16_t port) {
struct sockaddr_in* ipv4_addr = (struct sockaddr_in*)addr;
uint32_t ip_addr;
if( !addr )
return FALSE;
ip_addr = (ip==NULL) ? INADDR_ANY : inet_addr(ip);
if( ip_addr==INADDR_NONE )
return FALSE;
memset( addr, 0, sizeof(struct sockaddr) );
ipv4_addr->sin_family = AF_INET;
ipv4_addr->sin_addr.s_addr = ip_addr;
ipv4_addr->sin_port = htons( port );
return TRUE;
}
BOOL ks_net_address_make(struct sockaddr* addr, const char* ip_port) {
char buf[512];
char* p = buf;
char* ip = 0;
uint32_t port;
size_t len;
// IPv4, format(ip:port) or (port)
// for example: (255.255.255.255:5555) or (5555)
//
if( !ip_port )
return FALSE;
len = strlen(ip_port);
if( len > (sizeof(buf)-1) )
return FALSE;
memcpy(buf, ip_port, len+1);
while( *p && *p!=':' )
++p;
if( *p==':' ) {
*p++ = '\0';
port = strtoul(p, &ip, 0);
if( *ip!='\0' || (port > 0xFFFF) )
return FALSE;
ip = buf;
} else {
port = strtoul(buf, &p, 0);
if( *p!='\0' || (port > 0xFFFF) )
return FALSE;
}
return ks_net_address_make_ip_port(addr, ip, (uint16_t)port);
}
void ks_net_address_make_ipv4(struct sockaddr* addr, uint32_t ip, uint16_t port) {
struct sockaddr_in* ipv4_addr = (struct sockaddr_in*)addr;
memset( addr, 0, sizeof(struct sockaddr) );
ipv4_addr->sin_family = AF_INET;
ipv4_addr->sin_addr.s_addr = ip;
ipv4_addr->sin_port = htons( port );
}
BOOL ks_socket_connect(KSSocket* self, const struct sockaddr* addr, uint32_t connect_timeout_second) {
struct sockaddr_in must_bind_addr;
KSSockFD fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
memset(&must_bind_addr, 0, sizeof(must_bind_addr));
must_bind_addr.sin_family = AF_INET;
must_bind_addr.sin_addr.s_addr = INADDR_ANY;
must_bind_addr.sin_port = 0;
if( ks_sock_is_invalid(fd) )
goto error_return;
if( bind(fd, (const struct sockaddr*)&must_bind_addr, sizeof(must_bind_addr))!=0 )
goto error_return;
if( ks_sock_set_blocking(fd, FALSE)!=0 )
goto error_return;
if( connect(fd, addr, sizeof(struct sockaddr_in))!=0 ) {
self->connected = FALSE;
self->connect_start = ((uint32_t)time(NULL));
self->connect_timeout = connect_timeout_second;
self->err = ks_sock_errno();
#ifdef _WIN32
if( self->err!=WSAEWOULDBLOCK )
goto error_return;
#else
if( self->err!=EINPROGRESS )
goto error_return;
#endif
} else {
self->connected = TRUE;
}
ks_sock_set_tcp_nodelay(fd, TRUE);
self->fd = fd;
return TRUE;
error_return:
if( ks_sock_is_valid(fd) )
ks_sock_close(fd);
return FALSE;
}
void ks_socket_close(KSSocket* self) {
KSSockFD fd = self->fd;
if( ks_sock_is_invalid(fd) )
return;
ks_sock_close(fd);
self->fd = INVALID_SOCKET;
self->connected = FALSE;
}
void ks_socket_update(KSSocket* self) {
KSSockFD fd = self->fd;
int res, sz;
if( ks_sock_is_invalid(fd) )
return;
// connect
if( !self->connected ) {
res = recv(fd, (char*)&sz, 0, 0);
self->err = ks_sock_errno();
if( res >= 0 ) {
self->connected = TRUE;
} else if( res < 0 ) {
#ifdef _WIN32
if( self->err==WSAEWOULDBLOCK ) {
self->connected = TRUE;
} else if( self->err!=WSAENOTCONN ) {
ks_socket_close(self);
} else {
uint32_t passed = (uint32_t)time(NULL) - self->connect_start;
if( passed >= self->connect_timeout )
ks_socket_close(self);
}
#else
struct sockaddr addr;
socklen_t len = sizeof(addr);
if( getpeername(self->fd, &addr, &len)==0 ) {
self->connected = TRUE;
} else if( self->err!=EAGAIN && self->err!=EINTR ) {
ks_socket_close(self);
} else {
uint32_t passed = (uint32_t)time(NULL) - self->connect_start;
if( passed >= self->connect_timeout )
ks_socket_close(self);
}
#endif
}
return;
}
#ifdef _WIN32
#define __IS_EWOULDBLOCK_ERR (self->err!=WSAEWOULDBLOCK)
#else
#define __IS_EWOULDBLOCK_ERR (self->err && self->err!=EINTR && self->err!=EAGAIN)
#endif
// read & check socket error
if( ks_sock_is_valid(fd) ) {
sz = (int)(self->rbuf + self->rlen - self->rpos);
res = recv(fd, self->rpos, sz, 0);
self->err = ks_sock_errno();
if( res > 0 ) {
self->rpos += res;
} else if( res < 0 ) {
if( __IS_EWOULDBLOCK_ERR )
ks_socket_close(self);
}
}
// write
if( ks_sock_is_valid(fd) && (self->spos > self->sbuf) ) {
sz = (int)(self->spos - self->sbuf);
res = send(fd, self->sbuf, sz, 0);
if( res==sz ) {
self->spos = self->sbuf;
} else if( res > 0 ) {
sz -= res;
memmove(self->sbuf, (self->sbuf + res), sz);
self->spos = self->sbuf + sz;
} else if( sz < 0 ) {
self->err = ks_sock_errno();
if( __IS_EWOULDBLOCK_ERR )
ks_socket_close(self);
}
}
#undef __IS_EWOULDBLOCK_ERR
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。