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) 31 struct event; // From libevent 32 typedef int SOCKET; 33 #endif 34 35 // Implements a raw socket interface 36 class 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: ~ListenSocketDelegate()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