blob: 8d32a29b797cbd6f9d90fa5508af9ea7da32ef43 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
yangsu@google.comc5aeccd2011-07-17 14:42:08 +00008#ifndef SkNetIO_DEFINED
9#define SkNetIO_DEFINED
10
11#include <netinet/in.h>
12#include <sys/socket.h>
13#include "SkTypes.h"
14#include "SkStream.h"
15/* PACKET and HEADER Format */
16#define PACKET_SIZE 1024
17#define HEADER_SIZE 20
18#define CONTENT_SIZE 1004
19
20#define DEFAULT_PORT 15555
21
22#define NONBLOCKING_SOCKETS
23#ifdef NONBLOCKING_SOCKETS
24#define MAX_CLIENTS 3
25#else
26#define MAX_CLIENTS 1
27#endif
28
29class SkSocket {
30public:
31 SkSocket();
32 ~SkSocket();
33
34 enum State {
35 kError_state,
36 kBegin_state,
37 kIncomplete_state,
38 kDone_state
39 };
40
41 enum DataType {
42 kPipeAppend_type,
43 kPipeReplace_type,
44 kString_type,
45 kInt_type
46 };
47 /*
48 * Write data to the socket. Data is a pointer to the beginning of the data
49 * to be sent and dataSize specifies the number of bytes to send. This
50 * method will spread the data across multiple packets if the data can't all
51 * fit in a single packet. The method will write all the data to each of the
52 * socket's open connections until all the bytes have been successfully sent
53 * and return total the number of bytes written to all clients, unless there
54 * was an error during the transfer, in which case the method returns -1.
55 * For blocking sockets, write will block indefinitely if the socket at the
56 * other end of the connection doesn't receive any data.
57 */
58 int writePacket(void* data, size_t size, DataType type = kPipeAppend_type);
59
60 /*
61 * Read a logical packet from socket. The data read will be stored
62 * sequentially in the dataArray. This method will keep running until all
63 * the data in a logical chunk has been read (assembling multiple partial
64 * packets if necessary) and return the number of bytes successfully read,
65 * unless there was an error, in which case the method returns -1. NOTE: For
66 * nonblocking sockets, read will return 0 if there's nothing to read. For
67 * blocking sockets, read will block indefinitely if the socket doesn't
68 * receive any data.
69 * once
70 */
71 int readPacket(void (*onRead)(const void* data, size_t size,int cid,
72 DataType type, void*), void* context);
73
74 // Suspend network transfers until resume() is called. Leaves all
75 // connections in tact.
76 void suspendAll() { fReadSuspended = fWriteSuspended = true; }
77 // Resume all network transfers.
78 void resumeAll() { fReadSuspended = fWriteSuspended = false; }
79 // Other helper functions
80 void suspendRead() { fReadSuspended = true; }
81 void resumeRead() { fReadSuspended = false; }
82 void suspendWrite() { fWriteSuspended = true; }
83 void resumeWrite() { fWriteSuspended = false; }
84
85protected:
86 struct header {
87 bool done;
88 int bytes;
89 DataType type;
90 };
91
92 // Create a socket and return its file descriptor. Returns -1 on failure
93 int createSocket();
94 // Close the socket specifies by the socket file descriptor passed in. Will
95 // update fMaxfd
96 void closeSocket(int sockfd);
97
98 // called when a broken or terminated connection has been detected. Closes
99 // the socket file descriptor and removes it from the master set by default.
100 // Override to handle broken connections differently
101 virtual void onFailedConnection(int sockfd);
102
103 // set the socket specified by the socket file descriptor as nonblocking
104 void setNonBlocking(int sockfd);
105 // add the socket specified by the socket file descriptor to the master
106 // file descriptor set, which is used to in the select() to detect new data
107 // or connections
108 void addToMasterSet(int sockfd);
109
110 bool fConnected;
111 bool fReady;
112 bool fReadSuspended;
113 bool fWriteSuspended;
114 int fMaxfd;
115 int fPort;
116 int fSockfd;
117 // fMasterSet contains all the file descriptors to be used for read/write.
118 // For clients, this will only contain fSockfd. For servers, this will
119 // contain all the file descriptors associated with established connections
120 // to clients
121 fd_set fMasterSet;
122 timeval fTimeout;
123};
124
125/*
126 * TCP server. Can accept simultaneous connections to multiple SkTCPClients and
127 * read/write data back and forth using read/writePacket calls. Port number can
128 * be specified, but make sure that the clients use the same port for connections
129 */
130class SkTCPServer : public SkSocket {
131public:
132 SkTCPServer(int port = DEFAULT_PORT);
133 ~SkTCPServer();
134
135 // accept any incoming connections to the server, will only accept a limited
136 // number of clients (specified by MAX_CLIENTS) at a time. Returns -1 on
137 // error. For blocking sockets, this method will block until a client has
138 // connected
139 int acceptIncomingConnections();
140
141 // disconnect all connections to clients. Returns -1 on error
142 int disconnectAllConnections();
143private:
144 typedef SkSocket INHERITED;
145};
146
147/*
148 * TCP client. Will connect to the server specified in the constructor. If a
149 * port number is specified, make sure that it's the same as the port number on
150 * the server
151 */
152class SkTCPClient : public SkSocket {
153public:
154 SkTCPClient(const char* hostname, int port = DEFAULT_PORT);
155
156 // Connect to server. Returns -1 on error or failure. Make sure to call this
157 // before any read/write operation to make sure that a connection is
158 // is established or is still open and reconnect to server if necessary. For
159 // blocking sockets, this method will block until the connection is accepted
160 // by the server.
161 int connectToServer();
162
163 // Client needs to recreate the socket when a connection is broken because
164 // connect can only be called successfully once.
165 virtual void onFailedConnection(int sockfd);
166private:
167 sockaddr_in fServerAddr;
168 typedef SkSocket INHERITED;
169};
170
171#endif