00001 /* 00002 * $Id: ServerSocket.cpp,v 1.3 2002/07/11 16:56:12 mindstorm2600 Exp $ 00003 */ 00004 #include<stdio.h> 00005 #include<stdlib.h> 00006 #include<unistd.h> 00007 #include<sys/types.h> 00008 #include<sys/socket.h> 00009 #include<netinet/in.h> 00010 #include<arpa/inet.h> 00011 #include<netdb.h> 00012 #include<errno.h> 00013 #include<iostream.h> 00014 #include<signal.h> 00015 #include"ServerSocket.h" 00016 #include"Exception.h" 00017 00018 namespace clawsoft{ 00019 00020 extern void addSigpipeHandler(); 00021 00022 ServerSocket::ServerSocket(const int p, const int m){ 00023 setClassName("ServerSocket"); 00024 CreateSocket(p, m); 00025 } 00026 00027 int ServerSocket::CreateSocket(const int p, const int m){ 00028 int ret; 00029 sock = -1; 00030 port = p; 00031 maxConn = m; 00032 struct sockaddr_in name; 00033 struct linger opt; 00034 #ifdef SOLARIS 00035 char *ptr; 00036 #endif 00037 addSigpipeHandler(); 00038 sock = socket (PF_INET, SOCK_STREAM, 0); 00039 if (sock < 0){ 00040 switch(errno){ 00041 case EMFILE: 00042 throw ProcOutOfFileDescriptorsException(); 00043 break; 00044 case ENFILE: 00045 throw SysOutOfFileDescriptorsException(); 00046 break; 00047 default: 00048 throw IOException(); 00049 } 00050 } 00051 name.sin_family = AF_INET; 00052 name.sin_port = htons (port); 00053 name.sin_addr.s_addr = htonl (INADDR_ANY); 00054 00055 opt.l_onoff = 1; 00056 opt.l_linger = 0; 00057 #ifdef SOLARIS 00058 ptr = (char *)&opt; 00059 ret = setsockopt(sock, SOL_SOCKET, SO_LINGER, ptr, sizeof(opt)); 00060 #else 00061 ret = setsockopt(sock, SOL_SOCKET, SO_LINGER, (struct linger*)&opt, sizeof(opt)); 00062 #endif 00063 if(ret == -1){ 00064 throw NetworkException(); 00065 } 00066 00067 if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0){ 00068 switch(errno){ 00069 case EINVAL: 00070 throw SocketAlreadyBoundedException(); 00071 break; 00072 default: 00073 throw NetworkException(); 00074 } 00075 } 00076 return 1; 00077 } 00078 00079 Socket *ServerSocket::accept(){ 00080 int ss; 00081 struct sockaddr_in client; 00082 #ifdef SOLARIS 00083 int size; 00084 #else 00085 size_t size; 00086 #endif 00087 if(listen(sock, maxConn) != 0){ 00088 switch(errno){ 00089 case EADDRINUSE: 00090 throw SocketAlreadyUsedException(); 00091 break; 00092 default: 00093 throw NetworkException(); 00094 } 00095 } 00096 size = sizeof(client); 00097 if((ss = ::accept(sock, (sockaddr *)&client, &size)) == -1) 00098 return NULL; 00099 Socket *r = new Socket(ss, port); 00100 return r; 00101 } 00102 00103 void ServerSocket::close(){ 00104 if(sock >= 0){ 00105 ::close(sock); 00106 sock = -1; 00107 } 00108 } 00109 00110 00111 }; //end of namespace directive
Powered by: