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 static int _socket_loopback_server(int port, int type)
     32 {
     33     struct sockaddr_in addr;
     34 
     35     memset(&addr, 0, sizeof(addr));
     36     addr.sin_family = AF_INET;
     37     addr.sin_port = htons(port);
     38     addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
     39 
     40 
     41     int s = socket(AF_INET, type, 0);
     42     if (s < 0)
     43         return -1;
     44 
     45     int n = 1;
     46     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n));
     47 
     48     if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
     49         close(s);
     50         return -1;
     51     }
     52 
     53     if (type == SOCK_STREAM) {
     54         if (listen(s, 4) < 0) {
     55             close(s);
     56             return -1;
     57         }
     58     }
     59 
     60     return s;
     61 }
     62 
     63 TcpStream::TcpStream(size_t bufSize) :
     64     SocketStream(bufSize)
     65 {
     66 }
     67 
     68 TcpStream::TcpStream(int sock, size_t bufSize) :
     69     SocketStream(sock, bufSize)
     70 {
     71     // disable Nagle algorithm to improve bandwidth of small
     72     // packets which are quite common in our implementation.
     73 #ifdef _WIN32
     74     DWORD  flag;
     75 #else
     76     int    flag;
     77 #endif
     78     flag = 1;
     79     setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(flag) );
     80 }
     81 
     82 int TcpStream::listen(unsigned short port)
     83 {
     84     m_sock = _socket_loopback_server(port, SOCK_STREAM);
     85     if (!valid()) return int(ERR_INVALID_SOCKET);
     86 
     87     return 0;
     88 }
     89 
     90 SocketStream * TcpStream::accept()
     91 {
     92     int clientSock = -1;
     93 
     94     while (true) {
     95         struct sockaddr_in addr;
     96         socklen_t len = sizeof(addr);
     97         clientSock = ::accept(m_sock, (sockaddr *)&addr, &len);
     98 
     99         if (clientSock < 0 && errno == EINTR) {
    100             continue;
    101         }
    102         break;
    103     }
    104 
    105     TcpStream *clientStream = NULL;
    106 
    107     if (clientSock >= 0) {
    108         clientStream =  new TcpStream(clientSock, m_bufsize);
    109     }
    110     return clientStream;
    111 }
    112 
    113 int TcpStream::connect(unsigned short port)
    114 {
    115     return connect("127.0.0.1",port);
    116 }
    117 
    118 int TcpStream::connect(const char* hostname, unsigned short port)
    119 {
    120     m_sock = socket_network_client(hostname, port, SOCK_STREAM);
    121     if (!valid()) return -1;
    122     return 0;
    123 }
    124