Ruby
2.1.3p242(2014-09-19revision47630)
Main Page
Modules
Data Structures
Files
File List
Globals
ext
socket
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
}
179
Generated on Mon Sep 22 2014 11:05:30 for Ruby by
1.8.2