📄 mysocket.cpp
字号:
/* 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 + -