File: frisbee.cpp

package info (click to toggle)
dmtcp 2.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 6,496 kB
  • sloc: cpp: 33,592; ansic: 28,099; sh: 6,735; makefile: 1,950; perl: 1,690; python: 1,241; asm: 138; java: 13
file content (125 lines) | stat: -rw-r--r-- 3,419 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#undef NDEBUG
#include <assert.h>


void doAccept ( int& acceptSock, int listenSock );
void doConnect ( int& connectSock, struct hostent* host, int port,const char* hostname );

int main ( int argc, char ** argv )
{
  if ( argc!=4 && argc!=5 ){
    printf( "usage: player listen-port connect-host connect-port [starter]\n" );
    return -1;
  }

  int listenSock = socket ( AF_INET, SOCK_STREAM, 0 );
  int connectSock = socket ( AF_INET, SOCK_STREAM, 0 );
  int acceptSock = -1;
  assert ( listenSock>0 && connectSock>0 );

  int listenPort = atoi ( argv[1] );
  hostent *connectHost = gethostbyname ( argv[2] );
  int connectPort = atoi ( argv[3] );
  assert ( listenPort > 0 );
  assert ( connectHost!=NULL );
  assert ( connectPort > 0 );

  bool isStarterNode = (argc==5);

  //bind listen socket
  {
    sockaddr_in listenAddy;
    memset ( &listenAddy,0,sizeof ( listenAddy ) );
    listenAddy.sin_family = AF_INET;
    listenAddy.sin_addr.s_addr = INADDR_ANY;
    listenAddy.sin_port = htons ( listenPort );

    assert ( bind ( listenSock, ( sockaddr * ) &listenAddy, sizeof ( listenAddy ) ) >=0 );

    assert ( listen ( listenSock,5 ) >=0 );
  }

  {
    //std::cout << "starter node? [y/n] ";
    //std::string c;
    //std::cin >> c;
    //if ( c[0]=='y' || c[0]=='Y' ) isStarterNode = true;
  }

  if ( !isStarterNode )
  {
    std::cout << "accepting..."  << std::endl;
    doAccept ( acceptSock, listenSock );
    std::cout << "connecting..."  << std::endl;
    doConnect ( connectSock, connectHost, connectPort, argv[2] );
  }
  else
  {
    std::cout << "connecting..."  << std::endl;
    doConnect ( connectSock, connectHost, connectPort, argv[2] );
    std::cout << "accepting..."  << std::endl;
    doAccept ( acceptSock, listenSock );
  }
  std::cout << "ready" << std::endl;

  for ( ;; )
  {
    std::cout << "throw [a-z] or catch [C]?";
    std::cout.flush();
    std::string c = " ";
    std::cin >> c;
    if ( c[0] >= 'a' && c[0] <= 'z' )
    {
      std::cout << "throwing a '" << c[0] << "' to next player..." << std::endl;
      assert ( write ( connectSock,&c[0],1 ) ==1 ) ;
      fsync ( connectSock );
      std::cout << "throw complete." << std::endl;
    }
    else
    {
      std::cout << "catching from previos player..." << std::endl;
      assert ( read ( acceptSock,&c[0],1 ) ==1 );
      std::cout << "caught a '" << c[0] << "'." << std::endl;
    }
  }

  return 0;
}

void doAccept ( int& acceptSock, int listenSock )
{
  assert ( ( acceptSock = accept ( listenSock,NULL,NULL ) ) >0 );
}
void doConnect ( int& connectSock, hostent* host, int port,const char* hostname )
{
  sockaddr_in addr;
  memset ( &addr,0,sizeof ( addr ) );
  addr.sin_family = AF_INET;
  memcpy ( &addr.sin_addr.s_addr, host->h_addr, host->h_length );
  addr.sin_port = htons ( port );
  int fd = -1;
  for (size_t i = 0; i < 20; i++) {
    fd = connect ( connectSock, ( sockaddr* ) &addr,sizeof ( addr ) );
    if (fd != -1) {
      break;
    }
    // Sleep for 100 ms to allow the other process to do a bind.
    struct timespec t;
    t.tv_sec = 0;
    t.tv_nsec = 100 * 1000 * 1000;
    nanosleep(&t, NULL);
  }
  // If connect fails even after 20 tries, give up.
  assert(fd >= 0);
}