📄 clinksock.cpp
字号:
#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <sys/time.h>#include <time.h>#include <fcntl.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <arpa/inet.h>#include <errno.h>#include "../tools/global.h"//#include "../tools/cmsgctrl.h"#include "../tools/clogs.h"#include "../tools/csysstate.h"#include "clink.h"#include "clinksock.h"int clinksock::sockinit(){ setlinktype(LINK_TYPE_SOCK); return 0;}int clinksock::sockclear(){ sockinit(); return 0;}//构造函数clinksock::clinksock(){ sockinit();}//析构函数clinksock::~clinksock(){ sockclear();}/*//在有信号时,读当前连接的数据int clinksock::read(void *buff,int len,int flags=0){ int ret; if(true==this->isdead()) { seterror(LINK_ERROR_CANT); psysstate->setinfo(-1,"link is dead"); return -1; } ret=recv(this->getfd(),buff,len,0); if(ret==len) { return ret; } if(ret<0) { psysstate->setinfo(-1,"read sock error:%d,%s",errno,strerror(errno)); seterror(LINK_ERROR_CLOSE); return -1; } if(flags!=0) { int total=ret; int readlen; while(total<len) { readlen=recv(this->getfd(),(char *)buff+total,len - total,flags); if(readlen<=0) { psysstate->setinfo(-1,"read sock error:%d,%s",errno,strerror(errno)); seterror(LINK_ERROR_CLOSE); return -2; } total += readlen; } return len; } else { return ret; }}*//*//通过当前连接,写数据int clinksock::write(void *buff,int len,int flags=0){ int ret=-1; int writelen=len; char *p=(char *)buff; int error; int errorlen=sizeof(error); if(len<=0) { return len; } while(writelen>0) { ret=send(this->getfd(),p,writelen,flags); if(ret==-1) { seterror(LINK_ERROR_CLOSE); break; } if(0 == getsockopt(this->getfd(),SOL_SOCKET,SO_ERROR,&error,(socklen_t *)&errorlen)) { if(0 != error) { ret=-1; seterror(LINK_ERROR_CLOSE); break; } } writelen -= ret; p += ret; } if(ret==-1) {// writelogfile(TYPEERROR|DESTTX|DESTSTD|DISPALL,// "write socket %s error\n",this->getsockinfo()); return -1; } else {// writelogfile(TYPENORMAL|DESTTX|DESTSTD|DISPALL,// "write socket %s LEN=%d\n",this->getsockinfo(),len); return len; }}*///设置联接的属性int clinksock::setopt(int fd){ //设定检测联接有效 1 //设定联接检查时间默认2h=>600s //设定联接检查间隔默认75s=>5s //设定联接检查次数默认9次=>2 return setsocketkeep(fd,1,600,5,2);// return 0;}//接收连接fdint clinksock::accept(int fd,char checkmethod){ if(fd<=0) { return -1; } setfd(fd); if(LINK_CHECK_NOT==checkmethod) { setstate(LINK_STATE_GOOD); } else { setstate(LINK_STATE_CHECK); } setcheckmethod(checkmethod); setdirection(LINK_DIRE_ACCEPT); setopt(fd); return 0;}//联接超时void sig_connecttimeout(int signo,siginfo_t *pinfo,void *pother){ writelogfile(TYPEINFO|DESTSTD|DISPALL,"connect sigalrm catch\n");}//连接到指定地址和端口,返回联接句柄//如果网络掉线,connect需要花费1分钟左右的时间,//所以加入时间信号,减少时间int clinksock::connect(char *addr,unsigned short port){ int s; struct sigaction newaction; struct sigaction oldaction; int alarmtime; //创建 if((s =socket(PF_INET,SOCK_STREAM,0))<0) { writelogfile(TYPEERROR|DESTALL|DISPALL,"create socket error:%d\n",errno); psysstate->setinfo(-1,"create socket error:%d\n",errno); //从新起动 psysstate->setflag(FLAG_RESTART); return -1; } struct sockaddr_in addrin; int len=sizeof(addrin); memset(&addrin,0,len); //绑定 addrin.sin_family = PF_INET; addrin.sin_port = htons(0); addrin.sin_addr.s_addr = inet_addr("0.0.0.0"); if(bind(s,(struct sockaddr *)&addrin,len)<0) { close(s); writelogfile(TYPEERROR|DESTALL|DISPALL, "bind socket to ip:%s,port %d error:%d\n", inet_ntoa(addrin.sin_addr), ntohs(addrin.sin_port), errno); psysstate->setinfo(-2,"bind socket to ip:%s,port %d error:%d\n", inet_ntoa(addrin.sin_addr), ntohs(addrin.sin_port), errno); return -3; } setopt(s); //联接 memset(&addrin,0,len); addrin.sin_family = PF_INET; addrin.sin_port = htons(port); addrin.sin_addr.s_addr = inet_addr(addr); alarmtime=alarm(0); memset(&newaction,0,sizeof(struct sigaction)); newaction.sa_sigaction=sig_connecttimeout; newaction.sa_flags=SA_SIGINFO | SA_NOMASK; if(0 != sigaction(SIGALRM,&newaction,&oldaction)) { close(s); writelogfile(TYPEERROR|DESTALL|DISPALL,"connect set sig alrm error"); return -4; } alarm(CONNECTTIMEOUT); if (::connect(s,(struct sockaddr *)&addrin,len)!=0) { close(s);/* writelogfile(TYPEERROR|DESTALL|DISPALL, "connect socket to ip:%s,port %d error:%d\n", inet_ntoa(addrin.sin_addr), ntohs(addrin.sin_port), errno);*/ psysstate->setinfo(-3,"connect socket to ip:%s,port %d error:%d\n", inet_ntoa(addrin.sin_addr), ntohs(addrin.sin_port), errno); s=-5; } if(0 != sigaction(SIGALRM,&oldaction,NULL)) { close(s); writelogfile(TYPEERROR|DESTALL|DISPALL,"connect set sig alrm error"); return -6; } alarm(alarmtime); return s;}//连接到指定地址和端口int clinksock::connect(char *addr,unsigned short port,char checkmethod){ int s; s=this->connect(addr,port); if(s<=0) { return s; } setdirection(LINK_DIRE_LINKTO); if(LINK_CHECK_NOT == checkmethod) { this->setstate(LINK_STATE_GOOD); } else { this->setstate(LINK_STATE_CHECK); } setfd(s); setcheckmethod(checkmethod); return 0;}int clinksock::connect(void *pvoidarg){ int ret; if(NULL == pvoidarg) { return -1; } if(false == this->setlinkparam(pvoidarg,sizeof(ssockarg))) { return -1; } ssockarg *parg=(ssockarg *)pvoidarg; ret=this->connect(parg->addr,parg->port,parg->checkmethod); debugprint("connect %s:%d ret=%d\n",parg->addr,parg->port,ret);/* if(0 != ret) { psysstate->printallinfo(TYPEERROR|DESTALL|DISPALL); }*/ return ret;}//判断联接远方是否关闭bool clinksock::remoteisclosed(){ return (true==isvalidsocket(this->getfd())?false:true);/* char c; if(recv(this->getfd(),&c,1,MSG_PEEK|MSG_DONTWAIT)<=0) { return true; } return false;*/}int clinksock::getfrom(int *ip,unsigned short *port){ if(this->isdead()) return -1; struct sockaddr_in addr; int len=sizeof(addr); memset(&addr,0,len); if(getsockname(this->fd,(struct sockaddr *)&addr,(socklen_t *)&len)==-1) { writelogfile(TYPEERROR|DESTALL|DISPALL,"getsockname error:%d\n",errno); return -1; } *ip=(int)addr.sin_addr.s_addr; *port=ntohs(addr.sin_port); return 0;}int clinksock::getto(int *ip,unsigned short *port){ if(this->isdead()) return -1; struct sockaddr_in addr; int len=sizeof(addr); memset(&addr,0,len); if(getpeername(this->fd,(struct sockaddr *)&addr,(socklen_t *)&len)==-1) { writelogfile(TYPEERROR|DESTALL|DISPALL,"getpeername error:%d\n",errno); return -1; } *ip=(int)addr.sin_addr.s_addr; *port=ntohs(addr.sin_port); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -