Home | History | Annotate | Download | only in OpenglCodecCommon
      1 /*
      2 * Copyright (C) 2011 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 #include "TcpStream.h"
     17 #include <cutils/sockets.h>
     18 #include <errno.h>
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <unistd.h>
     22 #include <string.h>
     23 
     24 #ifndef _WIN32
     25 #include <netinet/in.h>
     26 #include <netinet/tcp.h>
     27 #else
     28 #include <ws2tcpip.h>
     29 #endif
     30 
     31 #define LISTEN_BACKLOG 4
     32 
     33 TcpStream::TcpStream(size_t bufSize) :
     34     SocketStream(bufSize)
     35 {
     36 }
     37 
     38 TcpStream::TcpStream(int sock, size_t bufSize) :
     39     SocketStream(sock, bufSize)
     40 {
     41     // disable Nagle algorithm to improve bandwidth of small
     42     // packets which are quite common in our implementation.
     43 #ifdef _WIN32
     44     DWORD  flag;
     45 #else
     46     int    flag;
     47 #endif
     48     flag = 1;
     49     setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(flag) );
     50 }
     51 
     52 int TcpStream::listen(char addrstr[MAX_ADDRSTR_LEN])
     53 {
     54     m_sock = socket_loopback_server(0, SOCK_STREAM);
     55     if (!valid())
     56         return int(ERR_INVALID_SOCKET);
     57 
     58     /* get the actual port number assigned by the system */
     59     struct sockaddr_in addr;
     60     socklen_t addrLen = sizeof(addr);
     61     memset(&addr, 0, sizeof(addr));
     62     if (getsockname(m_sock, (struct sockaddr*)&addr, &addrLen) < 0) {
     63         close(m_sock);
     64         return int(ERR_INVALID_SOCKET);
     65     }
     66     snprintf(addrstr, MAX_ADDRSTR_LEN - 1, "%hu", ntohs(addr.sin_port));
     67     addrstr[MAX_ADDRSTR_LEN-1] = '\0';
     68 
     69     return 0;
     70 }
     71 
     72 SocketStream * TcpStream::accept()
     73 {
     74     int clientSock = -1;
     75 
     76     while (true) {
     77         struct sockaddr_in addr;
     78         socklen_t len = sizeof(addr);
     79         clientSock = ::accept(m_sock, (sockaddr *)&addr, &len);
     80 
     81         if (clientSock < 0 && errno == EINTR) {
     82             continue;
     83         }
     84         break;
     85     }
     86 
     87     TcpStream *clientStream = NULL;
     88 
     89     if (clientSock >= 0) {
     90         clientStream =  new TcpStream(clientSock, m_bufsize);
     91     }
     92     return clientStream;
     93 }
     94 
     95 int TcpStream::connect(const char* addr)
     96 {
     97     int port = atoi(addr);
     98     return connect("127.0.0.1",port);
     99 }
    100 
    101 int TcpStream::connect(const char* hostname, unsigned short port)
    102 {
    103     m_sock = socket_network_client(hostname, port, SOCK_STREAM);
    104     if (!valid()) return -1;
    105     return 0;
    106 }
    107