Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

tcpserver.c
Go to the documentation of this file.
1 /************************************************
2
3 tcpserver.c -
4
5 created at: Thu Mar 31 12:21:29 JST 1994
6
7 Copyright (C) 1993-2007 Yukihiro Matsumoto
8
9 ************************************************/
10
11 #include "rubysocket.h"
12
13 /*
14 * call-seq:
15 * TCPServer.new([hostname,] port) => tcpserver
16 *
17 * Creates a new server socket bound to _port_.
18 *
19 * If _hostname_ is given, the socket is bound to it.
20 *
21 * serv = TCPServer.new("127.0.0.1", 28561)
22 * s = serv.accept
23 * s.puts Time.now
24 * s.close
25 *
26 * Internally, TCPServer.new calls getaddrinfo() function to
27 * obtain addresses.
28 * If getaddrinfo() returns multiple addresses,
29 * TCPServer.new tries to create a server socket for each address
30 * and returns first one that is successful.
31 *
32 */
33 static VALUE
34 tcp_svr_init(int argc, VALUE *argv, VALUE sock)
35 {
36 VALUE hostname, port;
37
38 rb_scan_args(argc, argv, "011", &hostname, &port);
39 return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER);
40 }
41
42 /*
43 * call-seq:
44 * tcpserver.accept => tcpsocket
45 *
46 * Accepts an incoming connection. It returns a new TCPSocket object.
47 *
48 * TCPServer.open("127.0.0.1", 14641) {|serv|
49 * s = serv.accept
50 * s.puts Time.now
51 * s.close
52 * }
53 *
54 */
55 static VALUE
56 tcp_accept(VALUE sock)
57 {
58 rb_io_t *fptr;
59 union_sockaddr from;
60 socklen_t fromlen;
61
62 GetOpenFile(sock, fptr);
63 fromlen = (socklen_t)sizeof(from);
64 return rsock_s_accept(rb_cTCPSocket, fptr->fd, &from.addr, &fromlen);
65 }
66
67 /*
68 * call-seq:
69 * tcpserver.accept_nonblock => tcpsocket
70 *
71 * Accepts an incoming connection using accept(2) after
72 * O_NONBLOCK is set for the underlying file descriptor.
73 * It returns an accepted TCPSocket for the incoming connection.
74 *
75 * === Example
76 * require 'socket'
77 * serv = TCPServer.new(2202)
78 * begin # emulate blocking accept
79 * sock = serv.accept_nonblock
80 * rescue IO::WaitReadable, Errno::EINTR
81 * IO.select([serv])
82 * retry
83 * end
84 * # sock is an accepted socket.
85 *
86 * Refer to Socket#accept for the exceptions that may be thrown if the call
87 * to TCPServer#accept_nonblock fails.
88 *
89 * TCPServer#accept_nonblock may raise any error corresponding to accept(2) failure,
90 * including Errno::EWOULDBLOCK.
91 *
92 * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED, Errno::EPROTO,
93 * it is extended by IO::WaitReadable.
94 * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
95 *
96 * === See
97 * * TCPServer#accept
98 * * Socket#accept
99 */
100 static VALUE
101 tcp_accept_nonblock(VALUE sock)
102 {
103 rb_io_t *fptr;
104 union_sockaddr from;
105 socklen_t fromlen;
106
107 GetOpenFile(sock, fptr);
108 fromlen = (socklen_t)sizeof(from);
109 return rsock_s_accept_nonblock(rb_cTCPSocket, fptr, &from.addr, &fromlen);
110 }
111
112 /*
113 * call-seq:
114 * tcpserver.sysaccept => file_descriptor
115 *
116 * Returns a file descriptor of a accepted connection.
117 *
118 * TCPServer.open("127.0.0.1", 28561) {|serv|
119 * fd = serv.sysaccept
120 * s = IO.for_fd(fd)
121 * s.puts Time.now
122 * s.close
123 * }
124 *
125 */
126 static VALUE
127 tcp_sysaccept(VALUE sock)
128 {
129 rb_io_t *fptr;
130 union_sockaddr from;
131 socklen_t fromlen;
132
133 GetOpenFile(sock, fptr);
134 fromlen = (socklen_t)sizeof(from);
135 return rsock_s_accept(0, fptr->fd, &from.addr, &fromlen);
136 }
137
138 void
139 rsock_init_tcpserver(void)
140 {
141 /*
142 * Document-class: TCPServer < TCPSocket
143 *
144 * TCPServer represents a TCP/IP server socket.
145 *
146 * A simple TCP server may look like:
147 *
148 * require 'socket'
149 *
150 * server = TCPServer.new 2000 # Server bind to port 2000
151 * loop do
152 * client = server.accept # Wait for a client to connect
153 * client.puts "Hello !"
154 * client.puts "Time is #{Time.now}"
155 * client.close
156 * end
157 *
158 * A more usable server (serving multiple clients):
159 *
160 * require 'socket'
161 *
162 * server = TCPServer.new 2000
163 * loop do
164 * Thread.start(server.accept) do |client|
165 * client.puts "Hello !"
166 * client.puts "Time is #{Time.now}"
167 * client.close
168 * end
169 * end
170 *
171 */
172 rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket);
173 rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0);
174 rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, 0);
175 rb_define_method(rb_cTCPServer, "sysaccept", tcp_sysaccept, 0);
176 rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1);
177 rb_define_method(rb_cTCPServer, "listen", rsock_sock_listen, 1); /* in socket.c */
178 }
tcp_svr_init
static VALUE tcp_svr_init(int argc, VALUE *argv, VALUE sock)
Definition: tcpserver.c:34
tcp_accept
static VALUE tcp_accept(VALUE sock)
Definition: tcpserver.c:56
rsock_sock_listen
VALUE rsock_sock_listen(VALUE sock, VALUE log)
Definition: socket.c:659
rb_io_t
Definition: io.h:61
rsock_s_accept
VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
Definition: init.c:571
GetOpenFile
#define GetOpenFile(obj, fp)
Definition: io.h:118
rb_cTCPSocket
VALUE rb_cTCPSocket
Definition: init.c:15
union_sockaddr
Definition: rubysocket.h:184
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:630
rb_io_t::fd
int fd
Definition: io.h:62
argc
int argc
Definition: ruby.c:131
rsock_init_tcpserver
void rsock_init_tcpserver(void)
Definition: tcpserver.c:139
socklen_t
int socklen_t
Definition: getaddrinfo.c:84
INET_SERVER
#define INET_SERVER
Definition: rubysocket.h:225
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
Qnil
#define Qnil
Definition: ruby.h:427
rb_cTCPServer
VALUE rb_cTCPServer
Definition: init.c:16
VALUE
unsigned long VALUE
Definition: ruby.h:88
tcp_accept_nonblock
static VALUE tcp_accept_nonblock(VALUE sock)
Definition: tcpserver.c:101
rubysocket.h
tcp_sysaccept
static VALUE tcp_sysaccept(VALUE sock)
Definition: tcpserver.c:127
rsock_s_accept_nonblock
VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len)
Definition: init.c:531
rsock_init_inetsock
VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type)
Definition: ipsocket.c:145
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
argv
char ** argv
Definition: ruby.c:132
union_sockaddr::addr
struct sockaddr addr
Definition: rubysocket.h:185