javacommons/comms/ipclib/socket/src/socket.cpp
changeset 21 2a9601315dfc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/comms/ipclib/socket/src/socket.cpp	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,201 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  ?Description
+*
+*/
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <sys/select.h>
+#ifndef __SYMBIAN32__
+#include <netinet/tcp.h>  // TCP_NODELAY
+#endif
+#include <string.h>
+
+#include "logger.h"
+
+#include "socket.h"
+
+const int INVALID_SOCKET = 0;
+
+namespace java
+{
+namespace comms
+{
+
+Socket::Socket() : mSocket(INVALID_SOCKET)
+{
+}
+
+Socket::Socket(int aSocket) : mSocket(aSocket)
+{
+    setSockOpts();
+}
+
+Socket::~Socket()
+{
+    close();
+}
+
+int Socket::open(int aPort)
+{
+    sockaddr_in addr;
+
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(aPort);
+    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+    mSocket = socket(AF_INET, SOCK_STREAM , 0);
+
+    setSockOpts();
+
+    int rc = connect(mSocket, (sockaddr*)&addr, sizeof(addr));
+
+    if (rc<0)
+    {
+        ELOG2(EJavaComms, "connect failed %d - %s", errno, strerror(errno));
+        close();
+    }
+    else
+    {
+        rc = 0;
+    }
+
+    return rc;
+}
+
+// returns: 0   ok
+//          < 0 in error
+int Socket::read(char *aBuf, int len)
+{
+    int rc = 0;
+    do
+    {
+        if (mSocket==INVALID_SOCKET) return -1;
+
+        fd_set readset;
+        FD_ZERO(&readset);
+        FD_SET(mSocket, &readset);
+
+        timeval tv;
+        tv.tv_sec = 600;
+        tv.tv_usec = 0;
+
+        rc = select(mSocket+1, &readset, 0, 0, &tv);
+
+        if (rc < 0 && errno != EINTR)
+        {
+            ELOG3(EJavaComms, "select failed %d - %s - fd=%d", errno, strerror(errno), mSocket);
+            break;
+        }
+        else if (rc > 0 && FD_ISSET(mSocket, &readset))
+        {
+            rc = recv(aBuf, len);
+            break;
+        }
+    }
+    while (1);
+
+    return rc;
+}
+
+
+// returns: 0   ok (all bytes read)
+//          < 0 in error
+int Socket::recv(char *aBuf, int len)
+{
+    int count = len;
+    while (count > 0)
+    {
+        int rc = ::recv(mSocket, aBuf, count, 0);
+
+        if (rc < 0)
+        {
+            if (errno == EINTR) continue;
+            WLOG3(EJavaComms, "recv failed %d - %s - fd=%d", errno, strerror(errno), mSocket);
+            return -1;
+        }
+        if (rc == 0)     // EOF
+        {
+//            LOG1(EJavaComms, EInfo, "EOF received - exiting fd=%d", mSocket);
+            return -1;
+        }
+        aBuf += rc;
+        count -= rc;
+    }
+    return 0;
+}
+
+// returns: 0   in ok
+//          < 0 in error
+int Socket::write(const char *aBuf, int len)
+{
+    int sent = 0;
+    do
+    {
+        int rc = send(mSocket, aBuf+sent, len-sent, 0);
+        if (rc > 0)
+            sent += rc;
+        else if (rc < 0 && errno != EINTR)
+        {
+            WLOG3(EJavaComms, "send failed %d - %s - fd=%d", errno, strerror(errno), mSocket);
+            return -1;
+        }
+    }
+    while (len > sent);
+
+    return 0;
+}
+
+int Socket::shutdown(int aHow)
+{
+    int rc = ::shutdown(mSocket, aHow);
+    if (rc<0) WLOG3(EJavaComms, "shutdown failed %d - %s - fd=%d", errno, strerror(errno), mSocket);
+
+    return rc;
+}
+
+void Socket::close()
+{
+    if (mSocket !=INVALID_SOCKET)
+    {
+        int rc = ::close(mSocket);
+        if (rc<0) WLOG3(EJavaComms, "close failed %d - %s - fd=%d", errno, strerror(errno), mSocket);
+
+        mSocket = INVALID_SOCKET;
+    }
+}
+
+int Socket::getSocket() const
+{
+    return mSocket;
+}
+
+void Socket::setSockOpts()
+{
+    int flag = 1;
+    int rc = setsockopt(mSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));
+    if (rc<0) ELOG3(EJavaComms, "setsockopt(SO_REUSEADDR) failed %d - %s - fd=%d", errno, strerror(errno), mSocket);
+
+    rc = setsockopt(mSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
+    if (rc<0) ELOG3(EJavaComms, "setsockopt(TCP_NODELAY) failed %d - %s - fd=%d", errno, strerror(errno), mSocket);
+}
+
+} // namespace comms
+} // namespace java