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

📄 mysocket.cpp

📁 Unix下用C语言进行网络编程的范例
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* File : mysocket.cpp  */

#include<string.h>
#include <fcntl.h>
#include "mysocket.h"

MySocket::MySocket()
// Socket constructor that performs no initialization other then
// setting default values for the socket data members.
{
  address_family = AF_INET;      // Default address family
  socket_type = SOCK_STREAM;     // Default socket type
  protocol_family = IPPROTO_TCP; // Default protocol family
  port_number = MySOCKET_DEFAULT_PORT; // Default port number
  Mysocket = -1;
  conn_socket = -1;
  bytes_read = bytes_moved = 0;
  is_connected = 0;
  is_bound = 0;
  socket_error = MySOCKET_NO_ERROR;
}

MySocket::MySocket(sa_family_t af, int st, int pf,
		   int port, char *hostname)
// Socket constructor used to initialize the socket according to the
// address family, socket type, and protocol family. A hostname name should
// only be specified for client sockets.
{
  Mysocket = -1;
  conn_socket = -1;
  bytes_read = bytes_moved = 0;
  is_connected = 0;
  is_bound = 0;
  socket_error = MySOCKET_NO_ERROR;

  // Initialize the socket. NOTE: Any errors detected during initialization
  // will be recorded in the socket_error member.
  InitSocket(af, st, pf, port, hostname);
}

MySocket::MySocket(int st, int port, char *hostname) 
// Socket constructor used to initialize the socket according to the
// socket type. A hostname name should only be specified for client
// sockets.
{
  Mysocket = -1;
  conn_socket = -1;
  bytes_read = bytes_moved = 0;
  is_connected = 0;
  is_bound = 0;
  socket_error = MySOCKET_NO_ERROR;

  // Initialize the socket. NOTE: Any errors detected during initialization
  // will be recorded in the socket_error member.
  InitSocket(st, port, hostname);
}

MySocket::~MySocket()
{
  Close();
}

int MySocket::Socket()
// Create a socket. Returns a valid socket descriptor or
// -1 if the socket cannot be initialized.
{
  Mysocket = socket(address_family, socket_type, protocol_family);
  if(Mysocket < 0)
    {
      socket_error = MySOCKET_INIT_ERROR;
      return -1;
    }

  return Mysocket;
}

int MySocket::InitSocket(sa_family_t af,
				 int st,
				 int pf,
				 int port, char *hostname)
// Create and initialize a socket according to the address family,
// socket type, and protocol family. The "hostname" variable is an
// optional parameter that allows clients to specify a server name.
// Returns a valid socket descriptor or -1 if the socket cannot be
// initialized. 
{

  address_family = af;
  socket_type = st;
  protocol_family = pf;
  port_number = port;

  // Put the server information into the server structure.
  sin.sin_family = address_family;

  if(hostname) {
    // Get the server's Internet address
    hostent *hostnm = gethostbyname(hostname); 
    if(hostnm == (struct hostent *) 0) {
      socket_error = MySOCKET_HOSTNAME_ERROR;
      return -1;
    }
    // Put the server information into the client structure.
    sin.sin_addr.s_addr = *((unsigned long *)hostnm->h_addr);
  }
  else   
    sin.sin_addr.s_addr = INADDR_ANY; // Use my IP address 
  sin.sin_port = htons(port_number);

  // Create a TCP/IP
  if(Socket() < 0) {
    socket_error = MySOCKET_INIT_ERROR;
    return -1;
  }

  return Mysocket;
}

int MySocket::InitSocket(int st, int port,
				 char *hostname)
// Create and initialize a socket according to the socket type. This 
// cross-platform fucntion will only accept SOCK_STREAM and SOCK_DGRAM
// socket types. The "hostname" variable is an optional parameter that 
// allows clients to specify a server name. Returns a valid socket 
// descriptor or -1 if the socket cannot be initialized. 
{
  address_family = AF_INET;
  port_number = port; 

  if(st == SOCK_STREAM) {
    socket_type = SOCK_STREAM;
    protocol_family = IPPROTO_TCP;
  }
  else if(st == SOCK_DGRAM) {
    socket_type = SOCK_DGRAM;
    protocol_family = IPPROTO_UDP;
  }
  else {
    socket_error = MySOCKET_SOCKETTYPE_ERROR;
    return -1;
  }

  // Put the server information into the server structure.
  sin.sin_family = address_family;

  if(hostname) {
    // Get the server's Internet address
    hostent *hostnm = gethostbyname(hostname); 
    if(hostnm == (struct hostent *) 0) {
      socket_error = MySOCKET_HOSTNAME_ERROR;
      return -1;
    }

    // Put the server information into the client structure.
    sin.sin_addr.s_addr = *((unsigned long *)hostnm->h_addr);
  }
  else   
    sin.sin_addr.s_addr = INADDR_ANY; // Use my IP address

  sin.sin_port = htons(port_number);

  // Create a TCP/IP socket
  if(Socket() < 0) {
    socket_error = MySOCKET_INIT_ERROR;
    return -1;
  }

  return Mysocket;
}

int MySocket::Bind()
// Bind the socket to a name so that other processes can
// reference it and allow this socket to receive messages.
// Returns -1 if an error occurs.
{
  int rv = bind(Mysocket, (struct sockaddr *)&sin, sizeof(sin));
  if(rv >= 0) {
    is_bound = 1;
  } 
  else {
    socket_error = MySOCKET_BIND_ERROR;
    is_bound = 0;
  }
  return rv;
}

int MySocket::Connect()
// Connect the socket to a client or server. On the client side
// a connect call is used to initiate a connection.
// Returns -1 if an error occurs.
{
  int rv = connect(Mysocket, (struct sockaddr *)&sin, sizeof(sin));
  if(rv >= 0) {
    is_connected = 1; 
  }
  else {
    socket_error = MySOCKET_CONNECT_ERROR;
    is_connected = 0;
  }
  return rv;
}

int MySocket::ReadSelect(int s, int seconds, int useconds)
// Function used to multiplex reads without polling. Returns false if a 
// reply time is longer then the timeout values. 
{
  struct timeval timeout;
  fd_set fds;
  FD_ZERO(&fds);
  FD_SET(s, &fds);

  timeout.tv_sec = seconds;
  timeout.tv_usec = useconds;

  // This function calls select() giving it the file descriptor of
  // the socket. The kernel reports back to this function when the file
  // descriptor has woken it up.
  return select(s+1, &fds, 0, 0, &timeout);
}

int MySocket::Recv(void *buf, int bytes, int flags)
// Receive a block of data from the bound 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 Recv(Mysocket, buf, bytes, flags);
}

int MySocket::Recv(void *buf, int bytes, int seconds, int useconds, int flags)
// Receive a block of data from the bound 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 Recv(Mysocket, buf, bytes, seconds, useconds, flags);
}

int MySocket::Send(const void *buf, int bytes, int flags)
// Send a block of data to the bound 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 Send(Mysocket, buf, bytes, flags);
}

int MySocket::Recv(int s, void *buf, int bytes, int flags)
// Receive a block of data from a specified 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.
{
  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 = recv(s, p, num_req-bytes_read, flags)) > 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::Recv(int s, void *buf, int bytes, 
		   int seconds, int useconds, int flags)
// Receive a block of data from a specified 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.
{
  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 = recv(s, p, num_req-bytes_read, flags)) > 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::Send(int s, const void *buf, int bytes, int flags)
// Send a block of data to a specified 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.
{
  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 empty
    if((num_moved = send(s, p, num_req-bytes_moved, flags)) > 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;
}

int MySocket::RemoteRecv(void *buf, int bytes, int seconds, int useconds, 
			 int flags)
// Receive a block of data from a remote socket in blocking mode with a
// specified timeout value. Returns the total number of bytes received or 
// -1 if an error occurs.
{
  return Recv(conn_socket, buf, bytes, seconds, useconds, flags);
}

int MySocket::RemoteRecv(void *buf, int bytes, int flags)
// Receive a block of data from a remote socket in blocking mode.
// Returns the total number of bytes received or -1 if an error occurs.
{
  return Recv(conn_socket, buf, bytes, flags);
}

int MySocket::RemoteSend(const void *buf, int bytes, int flags)
// Send a block of data to a remote socket and do not return
// until all the bytes have been written. Returns the total 
// number of bytes received or -1 if an error occurs.
{
  return Send(conn_socket, buf, bytes, flags);
}

void MySocket::ShutDown(int how)
// Used to close and un-initialize a full-duplex socket.
{
  bytes_moved = 0;
  bytes_read = 0;
  is_connected = 0;
  is_bound = 0;

  if(Mysocket != -1) shutdown(Mysocket, how);
  if(conn_socket != -1) shutdown(conn_socket, how);

  Mysocket = -1;
  conn_socket = -1;
}

void MySocket::ShutDown(int &s, int how)
// Used to close and un-initialize the specified full-duplex socket.
{
  if(s != -1) shutdown(s, how);
  s = -1;
}

void MySocket::ShutDownSocket(int how)
// Used to close a full-duplex server side socket.
{
  if(Mysocket != -1) shutdown(Mysocket, how);
  Mysocket = -1;
}

void MySocket::ShutDownRemoteSocket(int how)
// Used to close a full-duplex client side socket.
{
  if(conn_socket != -1) shutdown(conn_socket, how);
  conn_socket = -1;
}

void MySocket::Close()
// Close any and un-initialize any bound sockets.
{
  bytes_moved = 0;
  bytes_read = 0;
  is_connected = 0;
  is_bound = 0;

  if(Mysocket != -1) close(Mysocket);
  if(conn_socket != -1) close(conn_socket);

}

void MySocket::Close(int &s)
// Close the specified socket
{

  if(s != -1) close(s);
  s = -1;
}

void MySocket::CloseSocket()
// Close the server side socket
{
  if(Mysocket != -1) close(Mysocket);
  Mysocket = -1;
}

void MySocket::CloseRemoteSocket()
// Close the client socket
{

  if(conn_socket != -1) close(conn_socket);

  conn_socket = -1;
}

int MySocket::Listen(int max_connections)
// Listen for connections if configured as a server.
// The "max_connections" variable determines how many
// pending connections the queue will hold. Returns -1
// if an error occurs.
{
  int rv = listen(Mysocket,         // Bound socket
		  max_connections); // Number of connection request queue
  if(rv < 0) socket_error = MySOCKET_LISTEN_ERROR;
  return rv;
}

int MySocket::Accept()
// Accept a connect from a remote socket. An Accept() 
// call blocks the server until the a client requests 
// service. Returns a valid socket descriptor or -1 
// if an error occurs.
{
  // Length of client address
  int addr_size = (int)sizeof(remote_sin); 

  conn_socket = accept(Mysocket, (struct sockaddr *)&remote_sin, &addr_size);

  if(conn_socket < 0)
    {
      socket_error = MySOCKET_ACCEPT_ERROR;
      return -1;
    }

  return conn_socket;
}

⌨️ 快捷键说明

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