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