Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

socket.cpp

Go to the documentation of this file.
00001 
00002 #ifdef WIN32
00003 #pragma warning (disable:4786)
00004 #endif
00005 
00006 #include "socket_generic.h"
00007 #include "API/Core/System/error.h"
00008 
00010 // CL_Socket construction:
00011 
00012 CL_Socket::CL_Socket(int socket)
00013 : impl(new CL_Socket_Generic)
00014 {
00015         impl->add_ref();
00016         impl->sock = socket;
00017 }
00018 
00019 CL_Socket::CL_Socket(CL_Socket::Type type)
00020 : impl(new CL_Socket_Generic)
00021 {
00022         impl->add_ref();
00023 
00024         int in_type = SOCK_STREAM, in_proto = 0;
00025         switch (type)
00026         {
00027         case tcp: in_proto = SOCK_STREAM; break;
00028         case udp: in_proto = SOCK_DGRAM; break;
00029         }
00030 
00031         impl->sock = socket(AF_INET, in_type, in_proto);
00032         if (impl->sock < 0) throw CL_Error("CL_Socket::CL_Socket failed");
00033 }
00034 
00035 CL_Socket::CL_Socket(const CL_Socket &copy)
00036 : impl(copy.impl)
00037 {
00038         impl->add_ref();
00039 }
00040 
00041 CL_Socket::~CL_Socket()
00042 {
00043         if (impl) impl->release_ref();
00044 }
00045 
00047 // CL_Socket attributes:
00048 
00049 int CL_Socket::get_socket() const
00050 {
00051         return impl->sock;
00052 }
00053 
00054 CL_EventTrigger *CL_Socket::get_read_trigger() const
00055 {
00056         if (impl->read == NULL) impl->read = impl->create_read_trigger();
00057         return impl->read;
00058 }
00059 
00060 CL_EventTrigger *CL_Socket::get_write_trigger() const
00061 {
00062         if (impl->write == NULL) impl->write = impl->create_write_trigger();
00063         return impl->write;
00064 }
00065 
00066 CL_EventTrigger *CL_Socket::get_exception_trigger() const
00067 {
00068         if (impl->exception == NULL) impl->exception = impl->create_exception_trigger();
00069         return impl->exception;
00070 }
00071 
00072 CL_IPAddress CL_Socket::get_source_address() const
00073 {
00074         sockaddr_in addr_in;
00075         memset(&addr_in, 0, sizeof(addr_in));
00076         addr_in.sin_family = AF_INET;
00077 
00078         int size = sizeof(sockaddr_in);
00079 
00080         int result = getsockname(impl->sock, (sockaddr *) &addr_in, &size);
00081         if (result == 0) throw CL_Error("CL_Socket::get_source_address() failed.");
00082 
00083         return CL_Socket_Generic::create_ip_address(addr_in);
00084 }
00085 
00086 CL_IPAddress CL_Socket::get_dest_address() const
00087 {
00088         sockaddr_in addr_in;
00089         memset(&addr_in, 0, sizeof(addr_in));
00090         addr_in.sin_family = AF_INET;
00091 
00092         int size = sizeof(sockaddr_in);
00093 
00094         int result = getpeername(impl->sock, (sockaddr *) &addr_in, &size);
00095         if (result == 0) throw CL_Error("CL_Socket::get_dest_address() failed.");
00096 
00097         return CL_Socket_Generic::create_ip_address(addr_in);
00098 }
00099 
00100 CL_Signal_v0 &CL_Socket::sig_read_triggered()
00101 {
00102         return impl->sig_read_triggered;
00103 }
00104 
00105 CL_Signal_v0 &CL_Socket::sig_write_triggered()
00106 {
00107         return impl->sig_write_triggered;
00108 }
00109 
00110 CL_Signal_v0 &CL_Socket::sig_exception_triggered()
00111 {
00112         return impl->sig_exception_triggered;
00113 }
00114 
00116 // CL_Socket operations:
00117 
00118 void CL_Socket::set_nonblocking(bool nonblocking)
00119 {
00120 #ifdef WIN32
00121         u_long argp = nonblocking ? 1 : 0;
00122         ioctlsocket(impl->sock, FIONBIO, &argp);
00123 #else
00124         fcntl(impl->sock, F_SETFL, O_NONBLOCK, nonblocking ? 1 : 0);
00125 #endif
00126 }
00127 
00128 void CL_Socket::set_nodelay(bool nodelay)
00129 {
00130         static int sol_tcp = -1;
00131         if (sol_tcp == -1) sol_tcp = getprotobyname("tcp")->p_proto;
00132 
00133         int value = nodelay ? 1 : 0;
00134         setsockopt(impl->sock, sol_tcp, TCP_NODELAY, (const char *) &value, sizeof(int));
00135 }
00136 
00137 int CL_Socket::send(const void *data, int size)
00138 {
00139         int result = ::send(
00140                 impl->sock,
00141                 (const char *) data,
00142                 size,
00143                 0);
00144         if (result < 0) throw CL_Error("CL_Socket::send failed");
00145 
00146         if (impl->write) impl->write->start_listen();
00147         return result;
00148 }
00149 
00150 int CL_Socket::send(const void *data, int size, const CL_IPAddress &dest)
00151 {
00152         sockaddr_in addr_in = CL_Socket_Generic::create_sockaddr_in(dest);
00153 
00154         int result = ::sendto(
00155                 impl->sock,
00156                 (const char *) data,
00157                 size,
00158                 0,
00159                 (const sockaddr *) &addr_in,
00160                 sizeof(addr_in));
00161         if (result < 0) throw CL_Error("CL_Socket::send failed");
00162 
00163         if (impl->write) impl->write->start_listen();
00164         return result;
00165 }
00166 
00167 int CL_Socket::recv(void *data, int size)
00168 {
00169         int result = ::recv(impl->sock, (char *) data, size, 0);
00170         if (result < 0) throw CL_Error("CL_Socket::recv failed");
00171 
00172         if (impl->read) impl->read->start_listen();
00173         return result;
00174 }
00175 
00176 int CL_Socket::recv(void *data, int size, CL_IPAddress &from)
00177 {
00178         sockaddr_in addr_in;
00179         memset(&addr_in, 0, sizeof(addr_in));
00180         addr_in.sin_family = AF_INET;
00181 
00182         socklen_t addr_size = sizeof(addr_in);
00183 
00184         int result = ::recvfrom(
00185                 impl->sock,
00186                 (char *) data,
00187                 size,
00188                 0,
00189                 (sockaddr *) &addr_in,
00190                 &addr_size);
00191         if (result < 0) throw CL_Error("CL_Socket::recv failed");
00192 
00193         if (impl->read) impl->read->start_listen();
00194         from = CL_Socket_Generic::create_ip_address(addr_in);
00195         return result;
00196 }
00197 
00198 void CL_Socket::connect(const CL_IPAddress &address)
00199 {
00200         sockaddr_in addr_in = CL_Socket_Generic::create_sockaddr_in(address);
00201         int result = ::connect(impl->sock, (sockaddr *) &addr_in, sizeof(addr_in));
00202         if (result < 0) throw CL_Error("CL_Socket::connect failed");
00203         if (impl->read) impl->read->start_listen();
00204         if (impl->exception) impl->exception->start_listen();
00205 }
00206 
00207 void CL_Socket::shutdown(ShutdownHow how)
00208 {
00209         int in_how = 0;
00210         switch (how)
00211         {
00212         case shutdown_receive: in_how = 0; break;
00213         case shutdown_send:    in_how = 1; break;
00214         }
00215 
00216         int result = ::shutdown(impl->sock, in_how);
00217         if (result < 0) throw CL_Error("CL_Socket::shutdown failed");
00218 }
00219 
00220 void CL_Socket::bind(const CL_IPAddress &address)
00221 {
00222         sockaddr_in addr_in = CL_Socket_Generic::create_sockaddr_in(address);
00223         int result = ::bind(impl->sock, (const sockaddr *) &addr_in, sizeof(addr_in));
00224         if (result < 0) throw CL_Error("CL_Socket::bind failed");
00225 }
00226 
00227 void CL_Socket::listen(int backlog)
00228 {
00229         int result = ::listen(impl->sock, backlog);
00230         if (result < 0) throw CL_Error("CL_Socket::listen failed");
00231 }
00232 
00233 CL_Socket CL_Socket::accept()
00234 {
00235         int new_sock = ::accept(impl->sock, NULL, NULL);
00236         if (new_sock == INVALID_SOCKET) throw CL_Error("CL_Socket::accept failed");
00237         if (impl->read) impl->read->start_listen();
00238         return CL_Socket(new_sock);
00239 }
00240 
00242 // CL_Socket implementation:
00243 
00244 CL_Socket::CL_Socket(CL_Socket_Generic *impl)
00245 : impl(impl)
00246 {
00247         impl->add_ref();
00248 }

Generated at Wed Apr 4 19:54:03 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001