1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#include "socket.h"
#include "socketlistener.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
# include <netinet/in.h>
# include <netdb.h>
#include <iostream>
namespace rpc
{
Socket::Socket(SocketListener* aListener) : listener(aListener), isServer(false), fd(-1), isConnected(false)
{}
Socket::~Socket()
{}
void Socket::listen(int port) throw(SocketException)
{
fd = socket( PF_INET, SOCK_STREAM, 0 );
if(fd==-1)
throw SocketException("Could not create socket");
sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons((u_short) port);
int result = ::bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
if(result==-1)
throw SocketException("Could not bind to port");
result = ::listen(fd,5);
if(result==-1)
throw SocketException("Could not listen");
isServer = true;
// Turn on re-use
int i = 1;
setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int))==0;
}
Socket* Socket::accept(SocketListener* sl) throw(SocketException)
{
int newfd = ::accept(fd,NULL,NULL);
if(newfd==-1)
throw SocketException("Could not accept");
Socket* s = new Socket(sl);
s->setFd(newfd);
s->isConnected = true;
return s;
}
int Socket::read(void *buf,int len) throw(SocketException)
{
int result = ::recv(fd,buf,len,0);
if(result==0)
{
disconnect();
listener->onDisconnect( this );
}
else
if(result==-1)
{
if(errno==EAGAIN)
return 0;
perror("socket::read: ");
throw SocketException(strerror(errno));
}
return result;
}
int Socket::write(const void *buf,int len) throw(SocketException)
{
//std::cout << "Writing to fd: " << fd << std::endl;
int result = ::send(fd,buf,len,0);
if(result == -1) throw SocketException(strerror(errno));
return result;
}
void Socket::connect(const char* addr,int port)
{
fd = socket(PF_INET, SOCK_STREAM, 0 );
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
struct hostent *hp = gethostbyname(addr);
if (hp == 0)
throw SocketException("DNS lookup failed");
saddr.sin_family = hp->h_addrtype;
memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
saddr.sin_port = htons((u_short) port);
int result = ::connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
if( result==-1 )
{
if( errno!=EAGAIN && errno!=EWOULDBLOCK)
throw SocketException( strerror(errno) );
}
isConnected = true;
listener->onConnect( this );
}
void Socket::disconnect()
{
::shutdown(fd,SHUT_RDWR);
close(fd);
fd=-1;
isConnected = false;
}
/**
* SocketManager calls the following methods.
*
*/
void Socket::onRead( )
{
if(isServer)
listener->onIncoming(this);
else
listener->onRead(this);
}
}
|