📄 think_net.c
字号:
#include "think_net.h"
int think_netstart(void)
{
#ifdef __THINK_WINDOWS__
WSADATA data;
if(WSAStartup(MAKEWORD(2,2),&data)<0){
think_error(0,"[%s]:WSAStartup error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return -1;
}
#endif
return 0;
}
int think_netstop(void)
{
#ifdef __THINK_WINDOWS__
if(WSACleanup()<0){
think_error(0,"[%s]:WSACleanup error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return -1;
}
#endif
return 0;
}
THINK_NET *think_netconnect(const char *ip,unsigned short port)
{
struct sockaddr_in servaddr;
int sockfd;
THINK_NET *net;
bzero(&servaddr,sizeof(struct sockaddr_in));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(port);
if((servaddr.sin_addr.s_addr=inet_addr(ip))==INADDR_NONE){
think_error(0,"[%s]:inet_addr error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return NULL;
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
think_error(0,"[%s]:socket create error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return NULL;
}
if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(struct sockaddr_in))<0){
think_error(0,"[%s]:connect error.[%d:%s][%s:%d]",__func__,think_socketerrno,think_strerror(think_socketerrno),ip,port);
socketclose(sockfd);
return NULL;
}
if((net=malloc(sizeof(THINK_NET)))==NULL){
think_error(0,"[%s]:malloc error.[%d:%s]",__func__,think_errno,think_strerror(think_errno));
socketclose(sockfd);
return NULL;
}
memset(net,0x00,sizeof(THINK_NET));
net->sockfd=sockfd;
snprintf(net->ip,sizeof(net->ip),"%s",ip);
net->port=port;
return net;
}
THINK_NET *think_netlisten(const char *ip,unsigned short port)
{
struct sockaddr_in servaddr;
int sockfd;
struct linger so_linger;
int option;
THINK_NET *net;
bzero(&servaddr,sizeof(struct sockaddr_in));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(port);
if(strcmp(ip,"*")==0){
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
}else{
if((servaddr.sin_addr.s_addr=inet_addr(ip))==INADDR_NONE){
think_error(0,"[%s]:inet_addr error.[%d:%s][%s:%d]",__func__,think_socketerrno,think_strerror(think_socketerrno),ip,port);
return NULL;
}
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
think_error(0,"[%s]:socket create error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return NULL;
}
so_linger.l_onoff=1;
so_linger.l_linger=0;
if(setsockopt(sockfd,SOL_SOCKET,SO_LINGER,(void *)&so_linger,sizeof(so_linger))<0){
think_error(0,"[%s]:setsockopt error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
socketclose(sockfd);
return NULL;
}
option=1;
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(void *)&option,sizeof(option))<0){
think_error(0,"[%s]:setsockopt error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
socketclose(sockfd);
return NULL;
}
option=1;
if(setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,(void *)&option,sizeof(option))<0){
think_error(0,"[%s]:setsockopt error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
socketclose(sockfd);
return NULL;
}
if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0){
think_error(0,"[%s]:bind error.[%d:%s][%s:%d]",__func__,think_socketerrno,think_strerror(think_socketerrno),ip,port);
socketclose(sockfd);
return NULL;
}
if(listen(sockfd,5)<0){
think_error(0,"[%s]:listen error.[%d:%s][%s:%d]",__func__,think_socketerrno,think_strerror(think_socketerrno),ip,port);
socketclose(sockfd);
return NULL;
}
if((net=malloc(sizeof(THINK_NET)))==NULL){
think_error(0,"[%s]:malloc error.[%d:%s]",__func__,think_errno,think_strerror(think_errno));
socketclose(sockfd);
return NULL;
}
memset(net,0x00,sizeof(THINK_NET));
net->sockfd=sockfd;
snprintf(net->ip,sizeof(net->ip),"%s",ip);
net->port=port;
return net;
}
THINK_NET *think_netaccept(THINK_NET *net)
{
struct sockaddr_in addr;
socklen_t addrlen;
int sockfd;
char *p;
THINK_NET *client;
addrlen=sizeof(addr);
if((sockfd=accept(net->sockfd,(struct sockaddr *)&addr,&addrlen))<0){
think_error(0,"[%s]:accept error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return NULL;
}
if((p=inet_ntoa(addr.sin_addr))==NULL){
think_error(0,"[%s]:inet_ntoa error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return NULL;
}
if((client=malloc(sizeof(THINK_NET)))==NULL){
think_error(0,"[%s]:malloc error.[%d:%s]",__func__,think_errno,think_strerror(think_errno));
socketclose(sockfd);
return NULL;
}
memset(client,0x00,sizeof(THINK_NET));
client->sockfd=sockfd;
snprintf(client->ip,sizeof(client->ip),"%s",p);
client->port=ntohs(addr.sin_port);
return client;
}
int think_netrecv(THINK_NET *net,void *buf,unsigned int siz,int flags)
{
int n,nbytes;
for(nbytes=0;siz>0;nbytes+=n,siz-=n){
if((n=recv(net->sockfd,(char *)buf+nbytes,siz,0))<=0){
think_error(0,"[%s]:read error![%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return -1;
}
if(!(flags & THINK_NET_WAIT))
return n;
}
return nbytes;
}
int think_netsend(THINK_NET *net,const void *buf,unsigned int len,int flags)
{
int n,nbytes;
for(nbytes=0;len>0;nbytes+=n,len-=n){
if((n=send(net->sockfd,(char *)buf+nbytes,len,0))<=0){
think_error(0,"[%s]:write error![%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return -1;
}
if(!(flags & THINK_NET_WAIT))
return n;
}
return nbytes;
}
int think_netadd(THINK_NETLIST **netlist,THINK_NET *net)
{
THINK_NETLIST *head,*tail;
THINK_NETLIST *p;
if((p=malloc(sizeof(THINK_NETLIST)))==NULL){
think_error(0,"[%s]:malloc error.[%d:%s]",__func__,think_errno,think_strerror(think_errno));
return -1;
}
p->net=net;
p->prior=NULL;
p->next=NULL;
if(*netlist==NULL){
p->prior=p;
p->next=p;
*netlist=p;
}else{
head=*netlist;
tail=(*netlist)->prior;
p->prior=tail;
tail->next=p;
p->next=head;
head->prior=p;
}
return 0;
}
int think_netdel(THINK_NETLIST **netlist,THINK_NET *net)
{
THINK_NETLIST *p;
if((p=think_netfind(*netlist,net))==NULL){
think_error(0,"[%s]:net not found.",__func__);
return -1;
}
p->net=NULL;
return 0;
}
THINK_NETLIST *think_netfind(THINK_NETLIST *netlist,THINK_NET *net)
{
THINK_NETLIST *p;
if(netlist==NULL)
return NULL;
p=netlist;
do{
if(p->net==net)
return p;
p=p->next;
}while(p!=netlist);
return NULL;
}
int think_netclean(THINK_NETLIST **netlist)
{
THINK_NETLIST *next,*prior;
THINK_NETLIST *p;
if(*netlist==NULL)
return 0;
/* netclean */
p=*netlist;
do{
if(p==*netlist && p->net==NULL){
if(p==p->next){
*netlist=NULL;
free(p);
return 0;
}else{
*netlist=p->next;
next=p->next;
prior=p->prior;
prior->next=next;
next->prior=prior;
free(p);
p=*netlist;
continue;
}
}
if(p->net!=NULL){
p=p->next;
if(p==*netlist)
break;
continue;
}
next=p->next;
prior=p->prior;
prior->next=next;
next->prior=prior;
free(p);
p=next;
if(p==*netlist)
break;
}while(1);
return 0;
}
int think_netselect(THINK_NETLIST **netlist,int timeout)
{
fd_set fdrset,fdwset,fdeset;
int maxfd;
THINK_NET *net;
THINK_NETLIST *p;
struct timeval t,*pt;
int r;
think_netclean(netlist);
if(*netlist==NULL)
return 0;
FD_ZERO(&fdrset);
FD_ZERO(&fdwset);
FD_ZERO(&fdeset);
maxfd=0;
p=*netlist;
do{
net=p->net;
if(net->flags & THINK_NET_READ)
FD_SET(net->sockfd,&fdrset);
if(net->flags & THINK_NET_WRITE)
FD_SET(net->sockfd,&fdwset);
if(net->flags & THINK_NET_ERROR)
FD_SET(net->sockfd,&fdeset);
maxfd=net->sockfd>maxfd?net->sockfd:maxfd;
p=p->next;
}while(p!=*netlist);
if(timeout<0)
pt=NULL;
else{
pt=&t;
t.tv_sec=0;
t.tv_usec=timeout;
}
if((r=select(maxfd+1,&fdrset,&fdwset,&fdeset,pt))<0){
think_error(0,"[%s]:select error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return -1;
}
if(r==0)
return 0;
p=*netlist;
do{
net=p->net;
if(FD_ISSET(net->sockfd,&fdrset))
net->flags|=THINK_NET_READ;
if(FD_ISSET(net->sockfd,&fdwset))
net->flags|=THINK_NET_WRITE;
if(FD_ISSET(net->sockfd,&fdeset))
net->flags|=THINK_NET_ERROR;
p=p->next;
}while(p!=*netlist);
return r;
}
int think_netclose(THINK_NET *net)
{
THINK_NET_BUFLIST *p;
socketclose(net->sockfd);
/* free rlist */
while(net->rlist){
p=net->rlist;
if(p==p->next){
free(p);
break;
}
p->next->prior=p->prior;
p->prior->next=p->next;
net->rlist=p->next;
free(p);
}
/* free wlist */
while(net->wlist){
p=net->wlist;
if(p==p->next){
free(p);
break;
}
p->next->prior=p->prior;
p->prior->next=p->next;
net->wlist=p->next;
free(p);
}
free(net);
return 0;
}
int think_netsendtobuflist(THINK_NET *net,const void *buf,unsigned int len)
{
THINK_NET_BUFLIST *p,*head,*tail;
int pos,n;
char *buffer;
for(pos=0;pos<len;pos+=n,net->nwbytes+=n){
n=len-pos>THINK_NET_BUFSIZE?THINK_NET_BUFSIZE:len-pos;
if((buffer=malloc(n))==NULL){
think_error(0,"[%s]:malloc error![%d:%s]",__func__,think_errno,think_strerror(think_errno));
return -1;
}
memcpy(buffer,buf,n);
if((p=malloc(sizeof(THINK_NET_BUFLIST)))==NULL){
think_error(0,"[%s]:malloc error![%d:%s]",__func__,think_errno,think_strerror(think_errno));
free(buffer);
return -1;
}
memset(p,0x00,sizeof(THINK_NET_BUFLIST));
p->buf=(char *)buffer;
p->pos=0;
p->len=n;
p->prior=NULL;
p->next=NULL;
if(net->wlist==NULL){
p->next=p;
p->prior=p;
net->wlist=p;
}else{
head=net->wlist;
tail=net->wlist->prior;
p->prior=tail;
p->next=head;
tail->next=p;
head->prior=p;
}
}
return 0;
}
int think_netrecvtobuflist(THINK_NET *net)
{
THINK_NET_BUFLIST *p,*head,*tail;
char *buf;
int n;
if((buf=malloc(THINK_NET_BUFSIZE))==NULL){
think_error(0,"[%s]:malloc error![%d:%s]",__func__,think_errno,think_strerror(think_errno));
return -1;
}
if((n=think_netrecv(net,buf,THINK_NET_BUFSIZE,0))<=0){
think_errorerror();
free(buf);
return -1;
}
if((p=malloc(sizeof(THINK_NET_BUFLIST)))==NULL){
think_error(0,"[%s]:malloc error![%d:%s]",__func__,think_errno,think_strerror(think_errno));
free(buf);
return -1;
}
memset(p,0x00,sizeof(THINK_NET_BUFLIST));
p->buf=buf;
p->pos=0;
p->len=n;
p->prior=NULL;
p->next=NULL;
if(net->rlist==NULL){
p->prior=p;
p->next=p;
net->rlist=p;
}else{
head=net->rlist;
tail=net->rlist->prior;
p->prior=tail;
p->next=head;
tail->next=p;
head->prior=p;
}
net->nrbytes+=n;
return 0;
}
int think_netsendfrombuflist(THINK_NET *net)
{
THINK_NET_BUFLIST *p,*prior,*next;
char *buf;
int n,pos,len;
buf=net->wlist->buf;
len=net->wlist->len;
pos=net->wlist->pos;
if((n=think_netsend(net,buf+pos,len,0))<=0)
return -1;
net->nwbytes-=n;
len-=n;
pos+=n;
net->wlist->len=len;
net->wlist->pos=pos;
if(len>0)
return 0;
p=net->wlist;
if(p==p->next){
free(p->buf);
free(p);
net->wlist=NULL;
}else{
prior=p->prior;
next=p->next;
prior->next=next;
next->prior=prior;
net->wlist=next;
free(p->buf);
free(p);
}
return 0;
}
int think_netrecvfrombuflist(THINK_NET *net,void *buf,unsigned int siz)
{
THINK_NET_BUFLIST *p,*prior,*next;
int n,len;
for(len=0;len<siz;len+=n,net->nrbytes-=n){
p=net->rlist;
if(!p)
break;
n=siz-len>p->len?p->len:siz-len;
memcpy((char *)buf+len,p->buf+p->pos,n);
p->len-=n;
p->pos+=n;
if(p->len==0){
if(p==p->next){
free(p->buf);
free(p);
net->rlist=NULL;
}else{
prior=p->prior;
next=p->next;
prior->next=next;
next->prior=prior;
net->rlist=next;
free(p->buf);
free(p);
}
}
}
return len;
}
int think_netselectbybuflist(THINK_NETLIST **netlist,int timeout)
{
fd_set fdrset,fdwset,fdeset;
int maxfd;
THINK_NET *net;
THINK_NETLIST *p;
struct timeval t,*pt;
int r;
think_netclean(netlist);
if(*netlist==NULL)
return 0;
FD_ZERO(&fdrset);
FD_ZERO(&fdwset);
FD_ZERO(&fdeset);
maxfd=0;
p=*netlist;
do{
net=p->net;
net->flags&=~THINK_NET_READ;
net->flags&=~THINK_NET_WRITE;
net->flags&=~THINK_NET_ERROR;
FD_SET(net->sockfd,&fdrset); /* read */
if(net->wlist)
FD_SET(net->sockfd,&fdwset); /* write */
FD_SET(net->sockfd,&fdeset); /* error */
maxfd=net->sockfd>maxfd?net->sockfd:maxfd;
p=p->next;
}while(p!=*netlist);
if(timeout<0)
pt=NULL;
else{
pt=&t;
t.tv_sec=0;
t.tv_usec=timeout;
}
if((r=select(maxfd+1,&fdrset,&fdwset,&fdeset,pt))<0){
think_error(0,"[%s]:select error.[%d:%s]",__func__,think_socketerrno,think_strerror(think_socketerrno));
return -1;
}
if(r==0)
return 0;
p=*netlist;
do{
net=p->net;
if(FD_ISSET(net->sockfd,&fdrset))
net->flags|=THINK_NET_READ;
if(FD_ISSET(net->sockfd,&fdwset))
net->flags|=THINK_NET_WRITE;
if(FD_ISSET(net->sockfd,&fdeset))
net->flags|=THINK_NET_ERROR;
p=p->next;
}while(p!=*netlist);
return r;
}
int think_netpeekfrombuflist(THINK_NET *net,void *buf,unsigned int siz)
{
THINK_NET_BUFLIST *p;
int n,len;
len=0;
p=net->rlist;
do{
n=siz-len>p->len?p->len:siz-len;
memcpy((char *)buf+len,p->buf+p->pos,n);
len+=n;
if(len==siz)
break;
p=p->next;
}while(p!=net->rlist);
return len;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -