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

📄 mysocket.cpp

📁 《unix网络编程技术与分析》一书的C源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

int MySocket::GetSockName(int s, sockaddr_in *sa)
// Retrieves the current name for the specified socket descriptor.
// It is used on a bound and/or connected socket and returns the
// local association. This function is especially useful when a
// connect call has been made without doing a bind first in which
// case this function provides the only means by which you can
// determine the local association which has been set by the system.
// Returns -1 if an error occurs.
{
  int namelen = (int)sizeof(sockaddr_in);
  int rv = getsockname(s, (struct sockaddr *)sa, &namelen);
  if(rv < 0) socket_error = MySOCKET_SOCKNAME_ERROR;
  return rv;
}

int MySocket::GetSockName()
// Retrieves the current name for this objects socket descriptor.
// Returns -1 if an error occurs.
{
  return GetSockName(Mysocket, &sin);
}

int MySocket::GetPeerName(int s, sockaddr_in *sa)
// Retrieves the current name of the specified socket descriptor.
// Returns -1 if an error occurs.
{
  int namelen = (int)sizeof(sockaddr_in);
  int rv = getpeername(s, (struct sockaddr *)&sa, &namelen);
  if(rv < 0) socket_error = MySOCKET_PEERNAME_ERROR;
  return rv;
}

int MySocket::GetPeerName()
// Retrieves the current name for the remote socket descriptor.
// Returns -1 if an error occurs.
{
  return GetPeerName(conn_socket, &remote_sin);
}

int MySocket::GetSockOpt(int s, int level, int optName, 
			 void *optVal, unsigned *optLen)
// Gets the current socket option for the specified option level or name.
// Returns -1 if an error occurs.
{

  int rv = getsockopt(s, level, optName, optVal, (int *)optLen);
  if(rv < 0) socket_error = MySOCKET_SETOPTION_ERROR;
  return rv;
}

int MySocket::GetSockOpt(int level, int optName, void *optVal, 
			 unsigned *optLen)
// Gets the current socket option for the specified option level or name.
// Returns -1 if an error occurs.
{
  return GetSockOpt(Mysocket, level, optName, optVal, optLen);
}

int MySocket::SetSockOpt(int s, int level, int optName,
			 const void *optVal, unsigned optLen)
// Sets the current socket option for the specified option level or name.
// Returns -1 if an error occurs.
{

  int rv = setsockopt(s, level, optName, optVal, (int)optLen);
  if(rv < 0) socket_error = MySOCKET_SETOPTION_ERROR;
  return rv;
}

int MySocket::SetSockOpt(int level, int optName, const void *optVal, 
			 unsigned optLen)
// Sets the current socket option for the specified option level or name.
// Returns -1 if an error occurs.
{
  return SetSockOpt(Mysocket, level, optName, optVal, optLen);
}

servent *MySocket::GetServiceInformation(char *name, char *protocol)
// Function used to obtain service information about a specified name. 
// The source of this information is dependent on the calling function's
// platform configuration which should be a local services file or NIS 
// database. Returns a pointer to a servent data structure if service
// information is available or a null value if the service cannot be
// found. NOTE: The calling function must free the memory allocated
// for servent data structure upon each successful return.
{
  // If the "protocol" pointer is NULL, getservbyname returns
  // the first service entry for which the name matches the s_name
  // or one of the s_aliases. Otherwise getservbyname matches both
  // the name and the proto.
  servent *sp = getservbyname(name, protocol);
  if(sp == 0) return 0;

  servent *buf = new servent;
  if(!buf) return 0; // Memory allocation error
  memmove(buf, sp, sizeof(servent));
  return buf;
}

servent *MySocket::GetServiceInformation(int port, char *protocol)
// Function used to obtain service information about a specified port. 
// The source of this information is dependent on the calling function's
// platform configuration which should be a local services file or NIS 
// database. Returns a pointer to a servent data structure if service
// information is available or a null value if the service cannot be
// found. NOTE: The calling function must free the memory allocated
// for servent data structure upon each successful return.
{
  // If the "protocol" pointer is NULL, getservbyport returns the
  // first service entry for which the port matches the s_port.
  // Otherwise getservbyport matches both the port and the proto.
  servent *sp = getservbyport(port, protocol);
  if(sp == 0) return 0;

  servent *buf = new servent;
  if(!buf) return 0; // Memory allocation error
  memmove(buf, sp, sizeof(servent));
  return buf;
}

int MySocket::GetServByName(char *name, char *protocol)
// Set service information corresponding to a service name and protocol.
// Returns -1 if an unknown service or protocol is requested. NOTE: This
// information is obtained from this machines local services file or
// from a NIS database.
{
  // If the "protocol" pointer is NULL, getservbyname returns
  // the first service entry for which the name matches the s_name
  // or one of the s_aliases. Otherwise getservbyname matches both
  // the name and the proto.
  servent *sp = getservbyname(name, protocol);
  if(sp == 0) {
    socket_error = MySOCKET_PROTOCOL_ERROR;
    return -1;
  }
  sin.sin_port = sp->s_port;
  return 0;
}

int MySocket::GetServByPort(int port, char *protocol)
// Set service information corresponding to a port number and protocol.
// Returns -1 if an unknown service or protocol is requested. NOTE: This
// information is obtained from this machines local services file or
// from a NIS database.
{
  // If the "protocol" pointer is NULL, getservbyport returns the
  // first service entry for which the port matches the s_port.
  // Otherwise getservbyport matches both the port and the proto.
  servent *sp = getservbyport(port, protocol);
  if(sp == 0) {
    socket_error = MySOCKET_PROTOCOL_ERROR;
    return -1;
  }
  sin.sin_port = sp->s_port;
  return 0;
}

int MySocket::GetPortNumber()
// Return the port number actually set by the system. Use this function
// after a call to MySocket::GetSockName();
{
  return ntohs(sin.sin_port);
}

int MySocket::GetRemotePortNumber()
// Return the port number of the client socket.
{
  return ntohs(remote_sin.sin_port);
}

sa_family_t MySocket::GetAddressFamily()
// Returns the address family of this socket
{
  return sin.sin_family;
}

sa_family_t MySocket::GetRemoteAddressFamily()
// Returns the address family of the remote socket.
{
  return remote_sin.sin_family;  
}

hostent *MySocket::GetHostInformation(char *hostname)
// Function used to obtain hostname information about a specified host. 
// The source of this information is dependent on the calling function's
// platform configuration which should be a DNS, local host table, and/or
// NIS database. Returns a pointer to a hostent data structure
// if information is available or a null value if the hostname cannot be
// found. NOTE: The calling function must free the memory allocated
// for hostent data structure upon each successful return.
{
  in_addr hostia;
  hostent *hostinfo;
  hostia.s_addr = inet_addr(hostname);

  if(hostia.s_addr == NULL) { // Look up host by name
    hostinfo = gethostbyname(hostname); 
  }
  else {  // Look up host by IP address
    hostinfo = gethostbyaddr((const char *)&hostia, 
			     sizeof(in_addr), AF_INET);
  }
  if(hostinfo == (hostent *) 0) { // No host name info avialable
    return 0;
  }

  hostent *buf = new hostent;
  if(!buf) return 0; // Memory allocation error
  memmove(buf, hostinfo, sizeof(hostent));
  return buf;
}
  
int MySocket::GetHostName(char *sbuf)
// Pass back the host name of this machine in the "sbuf" variable.
// A memory buffer equal to "MysMAX_NAME_LEN" must be pre-allocated
// prior to using this function. Return -1 if an error occurs.
{
  // Prevent crashes if memory has not been allocated
  if(!sbuf) sbuf = new char[MysMAX_NAME_LEN]; 
  int rv = gethostname(sbuf, MysMAX_NAME_LEN);
  if(rv < 0) socket_error = MySOCKET_HOSTNAME_ERROR;
  return rv;
}

int MySocket::GetIPAddress(char *sbuf)
// Pass back the IP Address of this machine in the "sbuf" variable.
// A memory buffer equal to "MysMAX_NAME_LEN" must be pre-allocated
// prior to using this function. Return -1 if an error occurs.
{
  char hostname[MysMAX_NAME_LEN];
  int rv = GetHostName(hostname);
  if(rv < 0) return rv;

  in_addr *ialist;
  hostent *hostinfo = GetHostInformation(hostname);
  if(!hostinfo) {
    socket_error = MySOCKET_HOSTNAME_ERROR;
    return -1;
  }
  ialist = (in_addr *)hostinfo->h_addr_list[0];

  // Prevent crashes if memory has not been allocated
  if(!sbuf) sbuf = new char[MysMAX_NAME_LEN]; 

  strcpy(sbuf, inet_ntoa(*ialist));
  delete hostinfo;
  return 0;
}

int MySocket::GetDomainName(char *sbuf)
// Pass back the domain name of this machine in the "sbuf" variable.
// A memory buffer equal to "MysMAX_NAME_LEN" must be pre-allocated
// prior to using this function. Return -1 if an error occurs.
{
  char hostname[MysMAX_NAME_LEN];
  int rv = GetHostName(hostname);
  if(rv < 0) return rv;

  hostent *hostinfo = GetHostInformation(hostname);
  if(!hostinfo) {
    socket_error = MySOCKET_HOSTNAME_ERROR;
    return -1;
  }
  // Prevent crashes if memory has not been allocated
  if(!sbuf) sbuf = new char[MysMAX_NAME_LEN]; 

  strcpy(sbuf, hostinfo->h_name);
  int i; int len = strlen(sbuf);
  for(i = 0; i < len; i++) {
    if(sbuf[i] == '.') break;
  }
  if(++i < len) {
    len -= i;
    memmove(sbuf, sbuf+i, len);
    sbuf[len] = 0; // Null terminate the string
  }
  delete hostinfo;
  return 0;
}

int MySocket::GetBoundIPAddress(char *sbuf)
// Pass back the local or server IP address in the "sbuf" variable.
// A memory buffer equal to "MysMAX_NAME_LEN" must be pre-allocated
// prior to using this function. Return -1 if an error occurs.
{
  char *s = inet_ntoa(sin.sin_addr);
  if(s == 0) {
    socket_error = MySOCKET_HOSTNAME_ERROR;
    return -1;
  }

  // Prevent crashes if memory has not been allocated
  if(!sbuf) sbuf = new char[MysMAX_NAME_LEN]; 

  strcpy(sbuf, s);
  return 0;
}

int MySocket::GetRemoteHostName(char *sbuf)
// Pass back the client host name client in the "sbuf" variable.
// A memory buffer equal to "MysMAX_NAME_LEN" must be pre-allocated
// prior to using this function. Return -1 if an error occurs.
{
  char *s = inet_ntoa(remote_sin.sin_addr);
  if(s == 0) {
    socket_error = MySOCKET_HOSTNAME_ERROR;
    return -1;
  }

  // Prevent crashes if memory has not been allocated
  if(!sbuf) sbuf = new char[MysMAX_NAME_LEN]; 

  strcpy(sbuf, s);
  return 0;
}

void MySocket::GetClientInfo(char *client_name, int &r_port)
// Get the client's host name and port number. NOTE: This
// function assumes that a block of memory equal to the
// MysMAX_NAME_LEN constant has already been allocated.
{
  int rv = GetRemoteHostName(client_name);
  if(rv < 0) {
    char *unc = "UNKNOWN";
    for(unsigned i = 0; i < MysMAX_NAME_LEN; i++) client_name[i] = '\0';
    strcpy(client_name, unc);
  }
  r_port = GetRemotePortNumber();
}

int MySocket::RecvFrom(void *buf, int bytes, int seconds, int useconds, 
		       int flags)
// Receive a block of data from a remote datagram socket 
// and do not return until all the bytes have been read 
// or the timeout value has been exceeded. Returns the total 
// number of bytes received or -1 if an error occurs.
{
  return RecvFrom(Mysocket, &remote_sin, buf, bytes, seconds, useconds, flags);
}

int MySocket::RecvFrom(void *buf, int bytes, int flags)
// Receive a block of data from a remote datagram socket 
// and do not return until all the bytes have been read. 
// Returns the total number of bytes received or -1 if 
// an error occurs.
{
  return RecvFrom(Mysocket, &remote_sin, buf, bytes, flags);
}

int MySocket::SendTo(void *buf, int bytes, int flags)
// Send a block of data to a datagram socket and do not return
// until all the bytes have been written. Returns the total number
// of bytes sent or -1 if an error occurs.
{
  return SendTo(Mysocket, &sin, buf, bytes, flags);
}

int MySocket::RecvFrom(int s, sockaddr_in *sa, void *buf,
		       int bytes, int seconds, int useconds, int flags)
// Receive a block of data from a remote datagram socket 
// and do not return until all the bytes have been read 
// or the timeout value has been exceeded. Returns the total 
// number of bytes received or -1 if an error occurs.
{
  // Length of client address
  int addr_size = (int)sizeof(sockaddr_in); 
  bytes_read = 0;           // Reset the byte counter
  int num_read = 0;         // Actual number of bytes read
  int num_req = (int)bytes; // Number of bytes requested 
  char *p = (char *)buf;    // Pointer to the buffer

  while(bytes_read < bytes) { // Loop until the buffer is full
    if(!ReadSelect(s, seconds, useconds)) {
      socket_error = MySOCKET_REQUEST_TIMEOUT;
      return -1; // Exceeded the timeout value
    }
    if((num_read = recvfrom(s, p, num_req-bytes_read, flags, (struct sockaddr *)sa, &addr_size)) > 0) {
      bytes_read += num_read;   // Increment the byte counter
      p += num_read;            // Move the buffer pointer for the next read
    }
    if(num_read < 0) {
      socket_error = MySOCKET_RECEIVE_ERROR;
      return -1; // An error occurred during the read
    }
  }
  return bytes_read;
}

int MySocket::RecvFrom(int s, sockaddr_in *sa, void *buf,
		       int bytes, int flags)
// Receive a block of data from a remote datagram socket 
// and do not return until all the bytes have been read. 
// Returns the total number of bytes received or -1 if 
// an error occurs.
{
  // Length of client address
  int addr_size = (int)sizeof(sockaddr_in); 
  bytes_read = 0;           // Reset the byte counter
  int num_read = 0;         // Actual number of bytes read
  int num_req = (int)bytes; // Number of bytes requested 
  char *p = (char *)buf;    // Pointer to the buffer

  while(bytes_read < bytes) { // Loop until the buffer is full
    if((num_read = recvfrom(s, p, num_req-bytes_read, flags, (struct sockaddr *)sa, &addr_size)) > 0) {
      bytes_read += num_read;   // Increment the byte counter
      p += num_read;            // Move the buffer pointer for the next read
    }
    if(num_read < 0) {
      socket_error = MySOCKET_RECEIVE_ERROR;
      return -1; // An error occurred during the read
    }
  }
  return bytes_read;
}

int MySocket::SendTo(int s, sockaddr_in *sa, void *buf,
		     int bytes, int flags)
// Send a block of data to a datagram socket and do not return
// until all the bytes have been written. Returns the total number
// of bytes sent or -1 if an error occurs.
{
  // Length of address
  int addr_size = (int)sizeof(sockaddr_in);
  bytes_moved = 0;             // Reset the byte counter
  int num_moved = 0;           // Actual number of bytes written
  int num_req = (int)bytes;    // Number of bytes requested 
  char *p = (char *)buf;       // Pointer to the buffer

  while(bytes_moved < bytes) { // Loop until the buffer is full
    if((num_moved = sendto(s, p, num_req-bytes_moved, flags, (const struct sockaddr *)sa, addr_size)) > 0) {
      bytes_moved += num_moved;  // Increment the byte counter
      p += num_moved;            // Move the buffer pointer for the next read
    }
    if(num_moved < 0) {
      socket_error = MySOCKET_TRANSMIT_ERROR;
      return -1; // An error occurred during the read
    }
  }
  return bytes_moved;
}








⌨️ 快捷键说明

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