00001 #include <netinet/in.h>
00002 #include <sys/socket.h>
00003 #include <arpa/inet.h>
00004 #include "server_client.h"
00005 #include "tools/conversion.h"
00006 #include "engine/mutex.h"
00007
00008 Mutex inet_ntoa_mutex;
00009
00010 ServerClient::ServerClient(std::string _name, int _fd)
00011 : ClientCommon(_fd), FastLoopThreadObj(_name)
00012 {
00013 is_connected = true;
00014 client_host = "?.?.?.?";
00015 client_port = -1;
00016
00017 struct sockaddr_in sock;
00018 socklen_t sock_len = sizeof(sock);
00019 if(getsockname(_fd, (sockaddr*)&sock, &sock_len) != 0)
00020 log(LogError, "Unable to get peer address");
00021 else
00022 {
00023 inet_ntoa_mutex.Lock();
00024 client_host = inet_ntoa(sock.sin_addr);
00025 inet_ntoa_mutex.Unlock();
00026 client_port = sock.sin_port;
00027 }
00028 }
00029
00030 void ServerClient::Receive()
00031 {
00032 Lock();
00033 ClientCommon::Receive();
00034 Unlock();
00035 }
00036
00037 void ServerClient::Loop()
00038 {
00039 Lock();
00040
00041 if(!IsConnected())
00042 {
00043 Unlock();
00044 return;
00045 }
00046
00047 fd_set sock_set;
00048 memset(&sock_set, 0, sizeof(sock_set));
00049 FD_ZERO(&sock_set);
00050 FD_SET(fd, &sock_set);
00051
00052 struct timeval timeout;
00053 memset(&timeout, 0, sizeof(struct timeval));
00054
00055 timeout.tv_sec = 0;
00056 timeout.tv_usec = 100000;
00057
00058 if(select(fd + 1, &sock_set, NULL, NULL, &timeout) < 0)
00059 {
00060 if(timeout.tv_sec != 0 && timeout.tv_usec != 0)
00061 log(LogPanic, "Error during select");
00062 }
00063
00064 if(timeout.tv_sec == 0 && timeout.tv_usec == 0)
00065 {
00066 Unlock();
00067 return;
00068 }
00069
00070 if( FD_ISSET( fd, &sock_set) )
00071 {
00072 Receive();
00073 if(IsConnected())
00074 while(ParseBuffer())
00075 ;
00076 }
00077 else
00078 {
00079 log(LogInfo, "%s dirty disconnected", GetAddress().c_str());
00080 Disconnect();
00081 }
00082
00083 Unlock();
00084 }
00085
00086 const std::string ServerClient::GetAddress()
00087 {
00088 return client_host + std::string(":") + int2str(client_port);
00089 }
00090
00091 void ServerClient::Disconnect()
00092 {
00093 log(LogInfo, "%s disconnected", GetAddress().c_str());
00094 info_mutex.Lock();
00095 is_connected = false;
00096 info_mutex.Unlock();
00097 ClientCommon::Disconnect();
00098 }
00099
00100 bool ServerClient::IsConnected()
00101 {
00102 info_mutex.Lock();
00103 bool ret = is_connected;
00104 info_mutex.Unlock();
00105 return ret;
00106 }
00107