blob: f949c57322381ceb1464483d70377df3ccfb561c [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
#define _WINSOCKAPI_
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#ifdef SERVER_SOCKET_INC_MEMBER
SOCKET mServerSocket;
WSADATA mWsaData;
bool_t mIsBound;
#endif
#ifdef SERVER_SOCKET_INC_IMPL
inline ServerSocket::ServerSocket()
{
mServerSocket = INVALID_SOCKET;
mIsBound = false;
//Initialize Winsock
int32_t result = WSAStartup(MAKEWORD(2,2), &mWsaData);
if (result == 0) {
//create the socket which is used to connect the server
mServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (mServerSocket != INVALID_SOCKET) {
int32_t optVal = 1;
setsockopt(mServerSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&optVal, sizeof(optVal));
}
} else {
WSACleanup();
mServerSocket = INVALID_SOCKET;
}
}
inline ServerSocket::~ServerSocket()
{
close();
}
inline Socket* ServerSocket::accept()
{
SOCKET handle = ::accept(mServerSocket, NULL, NULL);
if (handle == INVALID_SOCKET) {
return NULL;
}
Socket *clientSocket = new Socket(handle);
return clientSocket;
}
inline status_t ServerSocket::close()
{
int32_t returnValue = CAPU_OK;
if (mServerSocket == INVALID_SOCKET) {
returnValue = CAPU_SOCKET_ESOCKET;
} else {
if (closesocket(mServerSocket) != 0) {
int32_t result = WSAGetLastError();
if (result != WSANOTINITIALISED){ //socket has already been closed
returnValue = CAPU_SOCKET_ECLOSE;
}
}
}
mServerSocket = INVALID_SOCKET;
mIsBound = false;
WSACleanup();
return returnValue;
}
inline status_t ServerSocket::bind(uint16_t port, const char *addr) {
if (port == 0) {
return CAPU_EINVAL;
}
//check if the address is valid
if (mIsBound) {
return CAPU_ERROR;
}
if (mServerSocket == INVALID_SOCKET)
return CAPU_SOCKET_ESOCKET;
sockaddr_in socketAddr;
memset((char*) &socketAddr, 0x00, sizeof(socketAddr));
socketAddr.sin_family = AF_INET;
if (addr == NULL) {
socketAddr.sin_addr.s_addr = INADDR_ANY;
} else if (inet_addr(addr) == INADDR_NONE) {
return CAPU_SOCKET_EADDR;
} else {
socketAddr.sin_addr.s_addr = inet_addr(addr);
}
socketAddr.sin_port = htons(port);
int32_t result = ::bind(mServerSocket, (sockaddr*) &socketAddr, sizeof(socketAddr));
if (result == SOCKET_ERROR) {
return CAPU_SOCKET_EBIND;
}
mIsBound = true;
return CAPU_OK;
}
inline status_t ServerSocket::listen(uint8_t backlog) {
if (!mIsBound) {
return CAPU_EINVAL;
}
if (mServerSocket == -1) {
return CAPU_SOCKET_ESOCKET;
}
int32_t result = ::listen(mServerSocket, backlog);
if (result == SOCKET_ERROR) {
return CAPU_ERROR;
}
return CAPU_OK;
}
#endif