1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// TCP/IP server that handles IO asynchronously in the specified MessageLoop. 6// These objects are NOT thread safe. They use WSAEVENT handles to monitor 7// activity in a given MessageLoop. This means that callbacks will 8// happen in that loop's thread always and that all other methods (including 9// constructors and destructors) should also be called from the same thread. 10 11#ifndef NET_BASE_LISTEN_SOCKET_H_ 12#define NET_BASE_LISTEN_SOCKET_H_ 13#pragma once 14 15#include "build/build_config.h" 16 17#if defined(OS_WIN) 18#include <winsock2.h> 19#endif 20#include <string> 21#if defined(OS_WIN) 22#include "base/win/object_watcher.h" 23#elif defined(OS_POSIX) 24#include "base/message_loop.h" 25#endif 26 27#include "base/basictypes.h" 28#include "base/memory/ref_counted.h" 29 30#if defined(OS_POSIX) 31struct event; // From libevent 32typedef int SOCKET; 33#endif 34 35// Implements a raw socket interface 36class ListenSocket : public base::RefCountedThreadSafe<ListenSocket>, 37#if defined(OS_WIN) 38 public base::win::ObjectWatcher::Delegate 39#elif defined(OS_POSIX) 40 public MessageLoopForIO::Watcher 41#endif 42{ 43 public: 44 // TODO(erikkay): this delegate should really be split into two parts 45 // to split up the listener from the connected socket. Perhaps this class 46 // should be split up similarly. 47 class ListenSocketDelegate { 48 public: 49 virtual ~ListenSocketDelegate() {} 50 51 // server is the original listening Socket, connection is the new 52 // Socket that was created. Ownership of connection is transferred 53 // to the delegate with this call. 54 virtual void DidAccept(ListenSocket *server, ListenSocket *connection) = 0; 55 virtual void DidRead(ListenSocket *connection, 56 const char* data, 57 int len) = 0; 58 virtual void DidClose(ListenSocket *sock) = 0; 59 }; 60 61 // Listen on port for the specified IP address. Use 127.0.0.1 to only 62 // accept local connections. 63 static ListenSocket* Listen(std::string ip, int port, 64 ListenSocketDelegate* del); 65 66 // Send data to the socket. 67 void Send(const char* bytes, int len, bool append_linefeed = false); 68 void Send(const std::string& str, bool append_linefeed = false); 69 70 // NOTE: This is for unit test use only! 71 // Pause/Resume calling Read(). Note that ResumeReads() will also call 72 // Read() if there is anything to read. 73 void PauseReads(); 74 void ResumeReads(); 75 76 protected: 77 friend class base::RefCountedThreadSafe<ListenSocket>; 78 79 enum WaitState { 80 NOT_WAITING = 0, 81 WAITING_ACCEPT = 1, 82 WAITING_READ = 3, 83 WAITING_CLOSE = 4 84 }; 85 86 static const SOCKET kInvalidSocket; 87 static const int kSocketError; 88 89 ListenSocket(SOCKET s, ListenSocketDelegate* del); 90 virtual ~ListenSocket(); 91 static SOCKET Listen(std::string ip, int port); 92 // if valid, returned SOCKET is non-blocking 93 static SOCKET Accept(SOCKET s); 94 95 virtual void SendInternal(const char* bytes, int len); 96 97 virtual void Listen(); 98 virtual void Accept(); 99 virtual void Read(); 100 virtual void Close(); 101 virtual void CloseSocket(SOCKET s); 102 103 // Pass any value in case of Windows, because in Windows 104 // we are not using state. 105 void WatchSocket(WaitState state); 106 void UnwatchSocket(); 107 108#if defined(OS_WIN) 109 // ObjectWatcher delegate 110 virtual void OnObjectSignaled(HANDLE object); 111 base::win::ObjectWatcher watcher_; 112 HANDLE socket_event_; 113#elif defined(OS_POSIX) 114 // Called by MessagePumpLibevent when the socket is ready to do I/O 115 virtual void OnFileCanReadWithoutBlocking(int fd); 116 virtual void OnFileCanWriteWithoutBlocking(int fd); 117 WaitState wait_state_; 118 // The socket's libevent wrapper 119 MessageLoopForIO::FileDescriptorWatcher watcher_; 120#endif 121 122 SOCKET socket_; 123 ListenSocketDelegate *socket_delegate_; 124 125 private: 126 bool reads_paused_; 127 bool has_pending_reads_; 128 129 DISALLOW_COPY_AND_ASSIGN(ListenSocket); 130}; 131 132#endif // NET_BASE_LISTEN_SOCKET_H_ 133