00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "precomp.h"
00030 #include "tcp_listen.h"
00031 #include "tcp_connection.h"
00032 #include "exception.h"
00033 #include "event.h"
00034 #include "string_help.h"
00035 #include "socket_event_handler.h"
00036 #ifdef WIN32
00037 #include <winsock.h>
00038 #define socklen_t int
00039 #else
00040 #include <sys/types.h>
00041 #include <sys/socket.h>
00042 #include <sys/time.h>
00043 #include <sys/types.h>
00044 #include <unistd.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <netdb.h>
00048 #endif
00049 #include <iostream>
00050
00052
00053
00054 CL_TCPListen::CL_TCPListen(const CL_String &port, int queue_size, bool force_bind)
00055 : handle(-1), socket_event_handler(0), accept_event(0)
00056 {
00057 handle = socket(PF_INET, SOCK_STREAM, 0);
00058 if (handle == -1)
00059 throw CL_Exception(TEXT("Socket create failed"));
00060
00061
00062
00063 int portI = CL_StringHelp::text_to_int(port);
00064
00065 sockaddr_in name;
00066 memset(&name, 0, sizeof(sockaddr_in));
00067 name.sin_family = AF_INET;
00068 name.sin_addr.s_addr = INADDR_ANY;
00069 name.sin_port = htons(portI);
00070
00071 int res = ::bind(handle, (sockaddr *) &name, sizeof(sockaddr_in));
00072 if (res != -1)
00073 res = ::listen(handle, queue_size);
00074 if (res == -1)
00075 {
00076 #ifdef WIN32
00077 closesocket(handle);
00078 #else
00079 close(handle);
00080 #endif
00081 throw CL_Exception(TEXT("Could not bind socket port ") + port);
00082 }
00083
00084 socket_event_handler = new CL_SocketEventHandler(handle);
00085 accept_event = new CL_Event(socket_event_handler, CL_Event::type_socket_read);
00086 }
00087
00088 CL_TCPListen::CL_TCPListen(const CL_String &address, const CL_String &port, int queue_size, bool force_bind)
00089 : handle(-1), socket_event_handler(0), accept_event(0)
00090 {
00091 std::string addressA = CL_StringHelp::text_to_local8(address);
00092 int portI = CL_StringHelp::text_to_int(port);
00093
00094 int ip = inet_addr(addressA.c_str());
00095 if (ip == INADDR_NONE)
00096 {
00097 hostent *host_info = gethostbyname(addressA.c_str());
00098 if (host_info == NULL)
00099 throw CL_Exception(TEXT("Could not lookup ") + address);
00100
00101 ip = *((int *) host_info->h_addr_list[0]);
00102 }
00103
00104 handle = socket(PF_INET, SOCK_STREAM, 0);
00105 if (handle == -1)
00106 throw CL_Exception(TEXT("Socket create failed"));
00107
00108 sockaddr_in name;
00109 memset(&name, 0, sizeof(sockaddr_in));
00110 name.sin_family = AF_INET;
00111 name.sin_addr.s_addr = ip;
00112 name.sin_port = htons(portI);
00113
00114 int res = ::bind(handle, (sockaddr *) &name, sizeof(sockaddr_in));
00115 if (res != -1)
00116 res = ::listen(handle, queue_size);
00117 if (res == -1)
00118 {
00119 #ifdef WIN32
00120 closesocket(handle);
00121 #else
00122 close(handle);
00123 #endif
00124 throw CL_Exception(TEXT("Could not bind socket on ") + address + TEXT(" port ") + port);
00125 }
00126
00127 socket_event_handler = new CL_SocketEventHandler(handle);
00128 accept_event = new CL_Event(socket_event_handler, CL_Event::type_socket_read);
00129 }
00130
00131 CL_TCPListen::~CL_TCPListen()
00132 {
00133 delete accept_event;
00134 delete socket_event_handler;
00135 #ifdef WIN32
00136 closesocket(handle);
00137 #else
00138 close(handle);
00139 #endif
00140 }
00141
00143
00144
00145 CL_Event *CL_TCPListen::get_accept_event()
00146 {
00147 return accept_event;
00148 }
00149
00151
00152
00153 CL_TCPConnection *CL_TCPListen::accept(int timeout)
00154 {
00155
00156
00157
00158 sockaddr_in name;
00159 memset(&name, 0, sizeof(sockaddr_in));
00160 name.sin_family = AF_INET;
00161
00162 socklen_t size = sizeof(sockaddr_in);
00163
00164 #ifdef WIN32
00165 SOCKET sock = ::accept(handle, (sockaddr *) &name, &size);
00166 if (sock == -1)
00167 return 0;
00168 #else
00169 int sock = ::accept(handle, (sockaddr *) &name, &size);
00170 if (sock == -1)
00171 return 0;
00172 #endif
00173 return new CL_TCPConnection(sock);
00174 }
00175
00177