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

📄 sockutil.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  else {    connDiagnostic("listening on port " << getLocalPort(s) <<                   " on interface " << formatAddress(interface));  }}// create a listener socket on the specified port and interfaceSOCKET interface_listen_socket(IPAddress interface, int port){  // create the socket and bind it to the interface and port  SOCKET s = create_socket();  bind_socket(s, interface, port);  // establish that this socket is listening for incoming connections  listen_socket(s, interface);  return s;}SOCKET interface_listen_socket_range(IPAddress interface,                                     PortRange const &range){  // same sequence of calls as interface_listen_socket  SOCKET s = create_socket();  bind_socket_range(s, interface, range);  listen_socket(s, interface);  return s;}#ifndef SOCKLEN_TYPE                   // for linux, set it to socklen_t; for other systems, sometimes  // it's unsigned long, sometimes it's int; we'll just guess  // socklen_t if nothing is specified  #define SOCKLEN_TYPE socklen_t#endif// accept a connectionSOCKET accept_socket(SOCKET s){  sockaddr saddr;  SOCKLEN_TYPE saddrLen = sizeof(saddr);  SOCKET ret = accept(s, &saddr, &saddrLen);  if (ret == INVALID_SOCKET) {    xsocket(s, "accept");  }  incOpenSockets();  connDiagnostic("accepted connection: " << sockInfo(ret));  return ret;}// format an IP address into normal decimal-dot notationstring formatAddress(IPAddress addr){  return stringb( ((addr >> 24) & 0xff) << "." <<                  ((addr >> 16) & 0xff) << "." <<		  ((addr >> 8) & 0xff) << "." <<		  (addr & 0xff) );}string formatAddress(IPAddress addr, int port){  return stringb(    formatAddress(addr) << ", port " << port );}// format a socket address into a stringstring formatAddress(sockaddr_in const &saddr){  // extract fields  IPAddress ip = ntohl(saddr.sin_addr.s_addr);  int port = ntohs(saddr.sin_port);  // write buffer  return formatAddress(ip, port);}// initiate a connectionSOCKET connect_socket(IPAddress ipaddr, int port, PortRange const *range){  // create address structure  sockaddr_in saddr;      // address of receiver  memset((char *)&saddr, 0, sizeof(saddr));  saddr.sin_family = AF_INET;  saddr.sin_port   = htons((short)port);    // get correct byte ordering  saddr.sin_addr.s_addr = htonl(ipaddr);  // create the socket  SOCKET s = create_socket();  // bind the socket locally if we've been asked to do so by 'range'  if (range) {    bind_socket_range(s, ipaddr, *range);  }  // connect the socket to the resolved address and port (sockaddr)  if (connect(s, (sockaddr *)&saddr, sizeof(saddr))       == SOCKET_ERROR) {    xsocket(s, "connect", true /*close*/);  }  connDiagnostic("connected: " << sockInfo(s));  return s;}void close_socket(SOCKET s){  #if DIAGNOSTIC && CONN_DIAGNOSTIC    int port;    try {      port = getLocalPort(s);      connDiagnostic("closing: " << sockInfo(s));    }    catch (...)      {}    // I don't care--the next will probably throw anyway  #endif  if (closesocket(s) == SOCKET_ERROR) {    xsocket(s, "closesocket");  }  decOpenSockets();}bool pollReadable(SOCKET s){  // make a SocketSet of one, and use its fn  SocketSet set;  set.add(s);  return set.pollReadable() > 0;   // it returns # of readable sockets}bool isClosed(SOCKET s){  // first, test to see if recv will block  if (!pollReadable(s)) {    // isn't readable, therefore can't be closed    // (or at least our OS can't have detected it)    return false;  }  char c;  int len = recv(s, &c, 1, MSG_PEEK);  if (len == 0) {    // socket closed    connDiagnostic("detected closed: " << sockInfo(s));    return true;  }  else if (len == SOCKET_ERROR) {    // some error    xsocket(s, "recv(MSG_PEEK)");  }  // not closed  return false;}// throw a particular exception if it's closedvoid checkClosed(SOCKET s){  if (isClosed(s)) {    xsocketClosed(s);  }}void getSockName(SOCKET s, sockaddr_in &addr){  SOCKLEN_TYPE namelen = sizeof(sockaddr_in);      if (getsockname(s, (sockaddr*)&addr, &namelen) == SOCKET_ERROR) {    xsocket(s, "getsockname");  }}IPAddress getLocalAddress(SOCKET s){  sockaddr_in saddr;  getSockName(s, saddr);  return ntohl(saddr.sin_addr.s_addr);}int getLocalPort(SOCKET s){  sockaddr_in saddr;  getSockName(s, saddr);  return ntohs(saddr.sin_port);}void getSockPeer(SOCKET s, sockaddr_in &addr){  SOCKLEN_TYPE namelen = sizeof(sockaddr_in);       if (getpeername(s, (sockaddr*)&addr, &namelen) == SOCKET_ERROR) {    xsocket(s, "getpeername");  }}IPAddress getRemoteAddress(SOCKET s){  sockaddr_in saddr;  getSockPeer(s, saddr);  return ntohl(saddr.sin_addr.s_addr);}int getRemotePort(SOCKET s){  sockaddr_in saddr;  getSockPeer(s, saddr);  return ntohs(saddr.sin_port);}void printSocketInfo(SOCKET s){  sockaddr_in saddr;  // get, display local name  getSockName(s, saddr);  printf("  local name: %s\n", (char const*)formatAddress(saddr));  // get, display remote name  try {    getSockPeer(s, saddr);    printf("  remote name: %s\n", (char const*)formatAddress(saddr));  }  catch (...) {    printf("  (not connected)\n");  }}bool isListening(SOCKET s){  #ifdef SO_ACCEPTCONN    long retval;    SOCKLEN_TYPE retvalLen = sizeof(retval);    int err = getsockopt(s, SOL_SOCKET, SO_ACCEPTCONN,                         (char*)&retval, &retvalLen);    if (err == SOCKET_ERROR) {      xsocket(s, "getsockopt");    }    return retval != 0;  #else    // turns out some systems don't have an easy way to detect    // if something is a listener (maybe winsock is only that does?)    // for now, I can tolerate simply not having this information    return false;  #endif}// this is a separate fn so we can use 'return' to// end collection of information but finish sockInfo normallyvoid sockInfoHelper(SOCKET s, stringBuilder &sb){  // test for special value  if (s == INVALID_SOCKET) {    sb << "invalid socket";    return;  }  // local address  sb << formatAddress(getLocalAddress(s)) <<        ":" << getLocalPort(s) << " - ";  // listening?  if (isListening(s)) {    sb << "(listener)";    return;  }  // remote address  sb << formatAddress(getRemoteAddress(s)) <<        ":" << getRemotePort(s);}// catch-all info retrievalstring sockInfo(SOCKET s){  // for accumulating results  stringBuilder sb;  sb << "[";  // I don't want exceptions here dirtying up my output  bool prev = xBase::logExceptions;  xBase::logExceptions = false;  try {    sockInfoHelper(s, sb);  }  catch (xBase &x) {    sb << "(" << x.why() << ")";  }  xBase::logExceptions = prev;  sb << "]";  return sb;}int getServByName(char const *serviceName){  struct servent *se = getservbyname(serviceName, "tcp");  if (!se) {    return 0;    // not found  }  int port = ntohs((short)se->s_port);  return port;}IPAddress resolveHostName(char const *hostname){  xassert(hostname);  // check for dotted decimal  try {                                   // if it is dotted decimal, this will simply parse it and return    return parseDottedDecimal(hostname);  }  catch (...)    {}       // not a valid decimal addr; go on to try DNS  // invoke the Domain Name Service (DNS)  // NOTE: This is a blocking operation, and may timeout only after  //       a substantial period of time.  hostent *he = gethostbyname(hostname);  if (he == NULL) {    xResolveFailure x(hostname);    THROW(x);  }  else {    // if multiple addresses are returned, we only return the first    return ntohl( *((unsigned long const*)he->h_addr_list[0]) );  }}// --------------------- parsing ----------------------IPAddress parseDottedDecimal(char const *decimalAddr){  IPAddress ret = ntohl(inet_addr(decimalAddr));  if (ret == INADDR_NONE) {    xfailure("inet_addr: invalid dotted-decimal address");  }  return ret;  #if 0  // this is supposedly the right way but some systems don't  // yet have inet_aton  struct in_addr addr;  if (!inet_aton(decimalAddr, &addr)) {    xfailure("inet_aton: invalid dotted-decimal address");  }  return ntohl(addr.s_addr);  #endif // 0}void parseAddrAndPort(IPAddress &ipaddr, int &port, char const *addrAndPort){  // separate on a colon, if present  StrtokParse tok(addrAndPort, ":");  if (tok == 2) {    // has both an IP address and a port    ipaddr = parseDottedDecimal(tok[0]);    port = atoi(tok[1]);  }  else if (tok == 1) {    // only a port is supplied    ipaddr = INADDR_ANY;    port = atoi(tok[0]);  }  else {    // wrong format    xfailure("parseAddrAndPort: address must be AAA.BBB.CCC.DDD:PPPP or PPPP format");  }}// ------------------ SocketSet ------------------------------------// timeout of 0 means poll without blocking// (this is expected to be const, but I don't tag// it as such for same reason 'timeout' parameter// to select is not so tagged (see sockutil.h))timeval SocketSet::timeZero = {0, 0};SocketSet::SocketSet(){  reset();}SocketSet::~SocketSet(){}bool SocketSet::contains(SOCKET s) const{  // on unix, we segfault if we test INVALID_SOCKET  if (s == INVALID_SOCKET) {    return false;  }                                            // FD_ISSET declared incorrectly in OSF1 system header files (doesn't mention const for fd_set*)  return !!FD_ISSET(s, ((fd_set*)&set));}void SocketSet::add(SOCKET s){  // this fn won't work after select is called  xassert(!used);  // silently filter out INVALID_SOCKETs  if (s == INVALID_SOCKET) {    return;  }  FD_SET(s, &set);  maxSocket = mymax(maxSocket, (unsigned)s);  numSockets++;}

⌨️ 快捷键说明

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