/* $Log: socket.cc,v $ * Revision 1.2 2003/05/22 20:57:39 stuart * convert to STL * * Revision 1.1 1999/05/13 20:52:20 stuart * Initial revision * */ #include #include #include #include #include #include extern "C" { #include #include } #include #pragma implementation #include "socket.h" InetAddress::InetAddress(const in_addr *sa) { haddr = new in_addr; if (sa) *haddr = *sa; else haddr->s_addr = (unsigned long)-1L; } InetAddress::InetAddress(const InetAddress &a) { haddr = new in_addr; *haddr = *a.haddr; } void InetAddress::operator=(const InetAddress &a) { *haddr = *a.haddr; } InetAddress::~InetAddress() { delete haddr; } InetAddress InetAddress::getByName(const char *name) { in_addr addr; addr.s_addr = (unsigned long)-1L; if (*name == '\0') return InetAddress(&addr); if (isdigit(*name)) { /* IP address. */ addr.s_addr = inet_addr(name); return InetAddress(&addr); } hostent *blob = gethostbyname(name); if (blob == NULL) return InetAddress(&addr); return InetAddress((in_addr *)blob->h_addr); } string InetAddress::getHostName() const { hostent *blob = gethostbyaddr((char *)haddr,sizeof (struct in_addr),AF_INET); return (blob == 0) ? "" : blob->h_name; } InetAddress InetAddress::getLocalHost() { char buf[256]; if (gethostname(buf,sizeof buf)) return 0; return getByName(buf); } in_addr InetAddress::getAddress() const { return *haddr; } string InetAddress::toString() const { return inet_ntoa(*haddr); } int Socket::bind(const InetAddress &a,int p) { sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_addr = a.getAddress(); saddr.sin_port = htons(p); int rc = ::bind(fd,(sockaddr*)&saddr,sizeof saddr); if (rc == 0) localport = p; return rc; } int Socket::bind(int p) { return bind(InetAddress::getLocalHost(),p); } int Socket::connect(const InetAddress &a,int p) { addr = a; port = p; sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_addr = addr.getAddress(); saddr.sin_port = htons(p); int rc = ::connect(fd,(sockaddr*)&saddr,sizeof saddr); if (rc >= 0) { size_t slen = sizeof saddr; if (getsockname(fd,(sockaddr*)&saddr,&slen)) localport = -1; else localport = saddr.sin_port; } return rc; } void Socket::setTcpNoDelay(bool f) { #ifdef TCP_NODELAY int nodelay = f; setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,&nodelay,sizeof nodelay); #endif } int Socket::connect(const char *host,int port) { return connect(addr.getByName(host),port); } Socket::Socket(bool stream): addr(0) { fd = socket(AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0); localport = -1; port = -1; } Socket::Socket(int fd): addr(0) { sockaddr_in saddr; size_t slen = sizeof saddr; if (getsockname(fd,(sockaddr*)&saddr,&slen)) localport = -1; else localport = saddr.sin_port; slen = sizeof saddr; if (getpeername(fd,(sockaddr*)&saddr,&slen)) port = -1; else { port = saddr.sin_port; addr = InetAddress(&saddr.sin_addr); } } Socket::~Socket() { close(fd); }