⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connection.cpp

📁 nsis是一个流传比较广的程序安装和解安装封装软件
💻 CPP
字号:
/*** JNetLib** Copyright (C) 2000-2001 Nullsoft, Inc.** Author: Justin Frankel** File: connection.cpp - JNL TCP connection implementation** License: see jnetlib.h*/#include "netinc.h"#include "util.h"#include "connection.h"JNL_Connection::JNL_Connection(JNL_AsyncDNS *dns, int sendbufsize, int recvbufsize){  m_errorstr="";  if (dns == JNL_CONNECTION_AUTODNS)  {    m_dns=new JNL_AsyncDNS();    m_dns_owned=1;  }  else  {    m_dns=dns;    m_dns_owned=0;  }  m_recv_buffer_len=recvbufsize;  m_send_buffer_len=sendbufsize;  m_recv_buffer=(char*)malloc(m_recv_buffer_len);  m_send_buffer=(char*)malloc(m_send_buffer_len);  m_socket=-1;  memset(m_recv_buffer,0,recvbufsize);  memset(m_send_buffer,0,sendbufsize);  m_remote_port=0;  m_state=STATE_NOCONNECTION;  m_recv_len=m_recv_pos=0;  m_send_len=m_send_pos=0;  m_host[0]=0;  memset(&m_saddr,0,sizeof(m_saddr));}void JNL_Connection::connect(int s, struct sockaddr_in *loc){  close(1);  m_socket=s;  m_remote_port=0;  m_dns=NULL;  if (loc) m_saddr=*loc;  else memset(&m_saddr,0,sizeof(m_saddr));  if (m_socket != -1)  {    SET_SOCK_BLOCK(m_socket,0);    m_state=STATE_CONNECTED;  }  else   {    m_errorstr="invalid socket passed to connect";    m_state=STATE_ERROR;  }}void JNL_Connection::connect(char *hostname, int port){  close(1);  m_remote_port=(short)port;  m_socket=::socket(AF_INET,SOCK_STREAM,0);  if (m_socket==-1)  {    m_errorstr="creating socket";    m_state=STATE_ERROR;  }  else  {    SET_SOCK_BLOCK(m_socket,0);    strncpy(m_host,hostname,sizeof(m_host)-1);    m_host[sizeof(m_host)-1]=0;    memset(&m_saddr,0,sizeof(m_saddr));    if (!m_host[0])    {      m_errorstr="empty hostname";      m_state=STATE_ERROR;    }    else    {      m_state=STATE_RESOLVING;      m_saddr.sin_family=AF_INET;      m_saddr.sin_port=htons((unsigned short)port);      m_saddr.sin_addr.s_addr=inet_addr(hostname);    }  }}JNL_Connection::~JNL_Connection(){  if (m_socket >= 0)  {    ::shutdown(m_socket, SHUT_RDWR);    ::closesocket(m_socket);    m_socket=-1;  }  free(m_recv_buffer);  free(m_send_buffer);  if (m_dns_owned)   {    delete m_dns;  }}void JNL_Connection::run(int max_send_bytes, int max_recv_bytes, int *bytes_sent, int *bytes_rcvd){  int bytes_allowed_to_send=(max_send_bytes<0)?m_send_buffer_len:max_send_bytes;  int bytes_allowed_to_recv=(max_recv_bytes<0)?m_recv_buffer_len:max_recv_bytes;  if (bytes_sent) *bytes_sent=0;  if (bytes_rcvd) *bytes_rcvd=0;  switch (m_state)  {    case STATE_RESOLVING:      if (m_saddr.sin_addr.s_addr == INADDR_NONE)      {        int a=m_dns?m_dns->resolve(m_host,(unsigned long int *)&m_saddr.sin_addr.s_addr):-1;        if (!a) { m_state=STATE_CONNECTING; }        else if (a == 1)        {          m_state=STATE_RESOLVING;           break;        }        else        {          m_errorstr="resolving hostname";           m_state=STATE_ERROR;           return;        }      }      if (!::connect(m_socket,(struct sockaddr *)&m_saddr,16))       {        m_state=STATE_CONNECTED;      }      else if (ERRNO!=EINPROGRESS)      {        m_errorstr="connecting to host";        m_state=STATE_ERROR;      }      else { m_state=STATE_CONNECTING; }    break;    case STATE_CONNECTING:      {        fd_set f[3];        FD_ZERO(&f[0]);        FD_ZERO(&f[1]);        FD_ZERO(&f[2]);        FD_SET(m_socket,&f[0]);        FD_SET(m_socket,&f[1]);        FD_SET(m_socket,&f[2]);        struct timeval tv;        memset(&tv,0,sizeof(tv));        if (select(m_socket+1,&f[0],&f[1],&f[2],&tv)==-1)        {          m_errorstr="connecting to host (calling select())";          m_state=STATE_ERROR;        }        else if (FD_ISSET(m_socket,&f[1]))         {          m_state=STATE_CONNECTED;        }        else if (FD_ISSET(m_socket,&f[2]))        {          m_errorstr="connecting to host";          m_state=STATE_ERROR;        }      }    break;    case STATE_CONNECTED:    case STATE_CLOSING:      if (m_send_len>0 && bytes_allowed_to_send>0)      {        int len=m_send_buffer_len-m_send_pos;        if (len > m_send_len) len=m_send_len;        if (len > bytes_allowed_to_send) len=bytes_allowed_to_send;        if (len > 0)        {          int res=::send(m_socket,m_send_buffer+m_send_pos,len,0);          if (res==-1 && ERRNO != EWOULDBLOCK)          {            //            m_state=STATE_CLOSED;//            return;          }          if (res>0)          {            bytes_allowed_to_send-=res;            if (bytes_sent) *bytes_sent+=res;            m_send_pos+=res;            m_send_len-=res;          }        }        if (m_send_pos>=m_send_buffer_len)         {          m_send_pos=0;          if (m_send_len>0)          {            len=m_send_buffer_len-m_send_pos;            if (len > m_send_len) len=m_send_len;            if (len > bytes_allowed_to_send) len=bytes_allowed_to_send;            int res=::send(m_socket,m_send_buffer+m_send_pos,len,0);            if (res==-1 && ERRNO != EWOULDBLOCK)            {//              m_state=STATE_CLOSED;            }            if (res>0)            {              bytes_allowed_to_send-=res;              if (bytes_sent) *bytes_sent+=res;              m_send_pos+=res;              m_send_len-=res;            }          }        }      }      if (m_recv_len<m_recv_buffer_len)      {        int len=m_recv_buffer_len-m_recv_pos;        if (len > m_recv_buffer_len-m_recv_len) len=m_recv_buffer_len-m_recv_len;        if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv;        if (len>0)        {          int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0);          if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK))          {                    m_state=STATE_CLOSED;            break;          }          if (res > 0)          {            bytes_allowed_to_recv-=res;            if (bytes_rcvd) *bytes_rcvd+=res;            m_recv_pos+=res;            m_recv_len+=res;          }        }        if (m_recv_pos >= m_recv_buffer_len)        {          m_recv_pos=0;          if (m_recv_len < m_recv_buffer_len)          {            len=m_recv_buffer_len-m_recv_len;            if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv;            if (len > 0)            {              int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0);              if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK))              {                        m_state=STATE_CLOSED;                break;              }              if (res > 0)              {                bytes_allowed_to_recv-=res;                if (bytes_rcvd) *bytes_rcvd+=res;                m_recv_pos+=res;                m_recv_len+=res;              }            }          }        }      }      if (m_state == STATE_CLOSING)      {        if (m_send_len < 1) m_state = STATE_CLOSED;      }    break;    default: break;  }}void JNL_Connection::close(int quick){  if (quick || m_state == STATE_RESOLVING || m_state == STATE_CONNECTING)  {    m_state=STATE_CLOSED;    if (m_socket >= 0)    {      ::shutdown(m_socket, SHUT_RDWR);      ::closesocket(m_socket);    }    m_socket=-1;    memset(m_recv_buffer,0,m_recv_buffer_len);    memset(m_send_buffer,0,m_send_buffer_len);    m_remote_port=0;    m_recv_len=m_recv_pos=0;    m_send_len=m_send_pos=0;    m_host[0]=0;    memset(&m_saddr,0,sizeof(m_saddr));  }  else  {    if (m_state == STATE_CONNECTED) m_state=STATE_CLOSING;  }}int JNL_Connection::send_bytes_in_queue(void){  return m_send_len;}int JNL_Connection::send_bytes_available(void){  return m_send_buffer_len-m_send_len;}int JNL_Connection::send(char *data, int length){  if (length > send_bytes_available())  {    return -1;  }    int write_pos=m_send_pos+m_send_len;  if (write_pos >= m_send_buffer_len)   {    write_pos-=m_send_buffer_len;  }  int len=m_send_buffer_len-write_pos;  if (len > length)   {    len=length;  }  memcpy(m_send_buffer+write_pos,data,len);  if (length > len)  {    memcpy(m_send_buffer,data+len,length-len);  }  m_send_len+=length;  return 0;}int JNL_Connection::send_string(char *line){  return send(line,strlen(line));}int JNL_Connection::recv_bytes_available(void){  return m_recv_len;}int JNL_Connection::peek_bytes(char *data, int maxlength){  if (maxlength > m_recv_len)  {    maxlength=m_recv_len;  }  int read_pos=m_recv_pos-m_recv_len;  if (read_pos < 0)   {    read_pos += m_recv_buffer_len;  }  int len=m_recv_buffer_len-read_pos;  if (len > maxlength)  {    len=maxlength;  }  memcpy(data,m_recv_buffer+read_pos,len);  if (len < maxlength)  {    memcpy(data+len,m_recv_buffer,maxlength-len);  }  return maxlength;}int JNL_Connection::recv_bytes(char *data, int maxlength){    int ml=peek_bytes(data,maxlength);  m_recv_len-=ml;  return ml;}int JNL_Connection::getbfromrecv(int pos, int remove){  int read_pos=m_recv_pos-m_recv_len + pos;  if (pos < 0 || pos > m_recv_len) return -1;  if (read_pos < 0)   {    read_pos += m_recv_buffer_len;  }  if (read_pos >= m_recv_buffer_len)  {    read_pos-=m_recv_buffer_len;  }  if (remove) m_recv_len--;  return m_recv_buffer[read_pos];}int JNL_Connection::recv_lines_available(void){  int l=recv_bytes_available();  int lcount=0;  int lastch=0;  int pos;  for (pos=0; pos < l; pos ++)  {    int t=getbfromrecv(pos,0);    if (t == -1) return lcount;    if ((t=='\r' || t=='\n') &&(         (lastch != '\r' && lastch != '\n') || lastch==t        )) lcount++;    lastch=t;  }  return lcount;}int JNL_Connection::recv_line(char *line, int maxlength){  if (maxlength > m_recv_len) maxlength=m_recv_len;  while (maxlength--)  {    int t=getbfromrecv(0,1);    if (t == -1)     {      *line=0;      return 0;    }    if (t == '\r' || t == '\n')    {      int r=getbfromrecv(0,0);      if ((r == '\r' || r == '\n') && r != t) getbfromrecv(0,1);      *line=0;      return 0;    }    *line++=(char)t;  }  return 1;}unsigned long JNL_Connection::get_interface(void){  if (m_socket==-1) return 0;  struct sockaddr_in sin;  memset(&sin,0,sizeof(sin));  socklen_t len=16;  if (::getsockname(m_socket,(struct sockaddr *)&sin,&len)) return 0;  return (unsigned long) sin.sin_addr.s_addr;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -