root/lang/cplusplus/friends_framework/trunk/test/proxy.cpp

Revision 15397, 2.6 kB (checked in by kazuho, 4 years ago)

switch to edge-trigger-based design

Line 
1#include <errno.h>
2#include <fcntl.h>
3#include "friends_framework.h"
4
5static CoopThreadMgr mgr(new CoopSocketMgr(), new CoopTimeoutMgr(600), 10);
6static sockaddr_in server_addr, my_addr;
7
8struct ProxyConn {
9  CoopRunnableSocket<ProxyConn> clientSock;
10  CoopRunnableSocket<ProxyConn> serverSock;
11  CoopRunnableTimeout<ProxyConn> timeout;
12  CoopBuffer dataToServer;
13  CoopBuffer dataToClient;
14  ProxyConn(int clientFd, sockaddr *, socklen_t)
15  : clientSock(&mgr, this, &ProxyConn::OnClientRead, &ProxyConn::OnClientWrite),
16    serverSock(&mgr, this, &ProxyConn::OnServerRead,
17               &ProxyConn::OnServerConnect),
18    timeout(&mgr, this, &ProxyConn::OnTimeout) {
19    clientSock.SetSock(clientFd);
20  }
21  ProxyConn *Init();
22  void ResetTimeout() {
23    timeout.SetTimeout(10 * mgr.TicksPerSecond());
24  }
25  void OnTimeout(CoopTimeout *) {
26    delete this;
27  }
28  void OnServerConnect(CoopSocket *) {
29    ResetTimeout();
30    clientSock.SetWaitForRead();
31    serverSock.SetWaitForRead();
32    serverSock.ClearWaitForWrite();
33    serverSock.writef = &ProxyConn::OnServerWrite;
34  }
35  void OnClientRead(CoopSocket *) {
36    ResetTimeout();
37    if (! CoopTransfer::OnRead(&clientSock, &serverSock, dataToServer))
38      delete this;
39  }
40  void OnServerWrite(CoopSocket *) {
41    ResetTimeout();
42    if (! CoopTransfer::OnWrite(&clientSock, &serverSock, dataToServer))
43      delete this;
44  }
45  void OnServerRead(CoopSocket *) {
46    ResetTimeout();
47    if (! CoopTransfer::OnRead(&serverSock, &clientSock, dataToClient))
48      delete this;
49  }
50  void OnClientWrite(CoopSocket *) {
51    ResetTimeout();
52    if (! CoopTransfer::OnWrite(&serverSock, &clientSock, dataToClient))
53      delete this;
54  }
55};
56
57ProxyConn *ProxyConn::Init()
58{
59  serverSock.SetSock(::socket(AF_INET, SOCK_STREAM, 0));
60  assert(serverSock.GetSock() != -1);
61  if (::connect(serverSock.GetSock(), reinterpret_cast<sockaddr*>(&server_addr),
62                sizeof(server_addr)) == -1) {
63    switch (errno) {
64    case EAGAIN:
65    case EINPROGRESS:
66      serverSock.SetWaitForWrite();
67      break;
68    default:
69      perror("failed to connect to server");
70      delete this;
71      return NULL;
72      }
73  } else {
74    OnServerConnect(&serverSock);
75  }
76  ResetTimeout();
77  return this;
78}
79
80int main(void)
81{
82  server_addr.sin_family = AF_INET;
83  server_addr.sin_addr.s_addr = htonl(0x7f000001);
84  server_addr.sin_port = htons(80);
85 
86  my_addr.sin_family = AF_INET;
87  my_addr.sin_addr.s_addr = htonl(0x7f000001);
88  my_addr.sin_port = htons(9999);
89 
90  if ((new CoopListener<ProxyConn>(&mgr))->Init(reinterpret_cast<sockaddr*>(&my_addr), sizeof(my_addr)) == NULL)
91    exit(1);
92 
93  mgr.Run();
94 
95  return 0;
96}
Note: See TracBrowser for help on using the browser.