blob: 1185373cf35dd4ea84abf373145fe9979bc07552 [file] [log] [blame]
/* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef SERVER_SOCKET_INC_HEADER
#include <sys/socket.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#ifdef SERVER_SOCKET_INC_MEMBER
private:
int32_t mServerSock;
bool_t mIsBound;
#endif
#ifdef SERVER_SOCKET_INC_IMPL
inline ServerSocket::ServerSocket() {
mServerSock = -1;
mIsBound = false;
mServerSock = socket(AF_INET, SOCK_STREAM, 0);
}
inline ServerSocket::~ServerSocket() {
close();
}
inline Socket* ServerSocket::accept() {
int32_t clientAddrSize = sizeof (sockaddr_in);
struct sockaddr_in serverAddr;
capu::int32_t socketHandle = ::accept(mServerSock, (sockaddr *) & serverAddr, (socklen_t *) & clientAddrSize);
if (socketHandle < 0) {
return NULL;
}
Socket *s = new Socket(socketHandle);
s->mServerAddress = serverAddr;
return s;
}
inline status_t ServerSocket::close() {
int32_t returnValue = CAPU_OK;
if (mServerSock != -1) {
shutdown(mServerSock, SHUT_RDWR);
if (::close(mServerSock) < 0) {
returnValue = CAPU_ERROR;
}
} else {
returnValue = CAPU_SOCKET_ESOCKET;
}
mServerSock = -1;
mIsBound = false;
return returnValue;
}
inline status_t ServerSocket::bind(uint16_t port, const char * addr) {
sockaddr_in mServerAddress;
if (port == 0)
return CAPU_EINVAL;
if (mIsBound)
return CAPU_ERROR;
if (mServerSock == -1)
return CAPU_SOCKET_ESOCKET;
int32_t optval = 1;
setsockopt(mServerSock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval));
memset((char *) &mServerAddress, 0x00, sizeof (mServerAddress));
mServerAddress.sin_family = AF_INET;
if (addr == NULL)
mServerAddress.sin_addr.s_addr = INADDR_ANY;
else if (inet_aton(addr, &mServerAddress.sin_addr) == 0)
return CAPU_SOCKET_EADDR;
mServerAddress.sin_port = htons(port);
int32_t res = ::bind(mServerSock, (sockaddr *) & mServerAddress, sizeof (struct sockaddr_in));
if (res < 0) {
return CAPU_SOCKET_EBIND;
}
mIsBound = true;
return CAPU_OK;
}
inline status_t ServerSocket::listen(uint8_t backlog) {
if (!mIsBound)
return CAPU_EINVAL;
if (mServerSock == -1)
return CAPU_SOCKET_ESOCKET;
if (::listen(mServerSock, backlog) < 0)
return CAPU_ERROR;
return CAPU_OK;
}
#endif