Ruby
1.9.3p484(2013-11-22revision43786)
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
static
VALUE
27
tcp_svr_init
(
int
argc
,
VALUE
*
argv
,
VALUE
sock)
28
{
29
VALUE
hostname, port;
30
31
rb_scan_args
(argc, argv,
"011"
, &hostname, &port);
32
return
rsock_init_inetsock
(sock, hostname, port,
Qnil
,
Qnil
,
INET_SERVER
);
33
}
34
35
/*
36
* call-seq:
37
* tcpserver.accept => tcpsocket
38
*
39
* TCPServer.open("127.0.0.1", 14641) {|serv|
40
* s = serv.accept
41
* s.puts Time.now
42
* s.close
43
* }
44
*
45
*/
46
static
VALUE
47
tcp_accept
(
VALUE
sock)
48
{
49
rb_io_t
*fptr;
50
struct
sockaddr_storage
from;
51
socklen_t fromlen;
52
53
GetOpenFile
(sock, fptr);
54
fromlen = (socklen_t)
sizeof
(from);
55
return
rsock_s_accept
(
rb_cTCPSocket
, fptr->
fd
,
56
(
struct
sockaddr*)&from, &fromlen);
57
}
58
59
/*
60
* call-seq:
61
* tcpserver.accept_nonblock => tcpsocket
62
*
63
* Accepts an incoming connection using accept(2) after
64
* O_NONBLOCK is set for the underlying file descriptor.
65
* It returns an accepted TCPSocket for the incoming connection.
66
*
67
* === Example
68
* require 'socket'
69
* serv = TCPServer.new(2202)
70
* begin # emulate blocking accept
71
* sock = serv.accept_nonblock
72
* rescue IO::WaitReadable, Errno::EINTR
73
* IO.select([serv])
74
* retry
75
* end
76
* # sock is an accepted socket.
77
*
78
* Refer to Socket#accept for the exceptions that may be thrown if the call
79
* to TCPServer#accept_nonblock fails.
80
*
81
* TCPServer#accept_nonblock may raise any error corresponding to accept(2) failure,
82
* including Errno::EWOULDBLOCK.
83
*
84
* If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED, Errno::EPROTO,
85
* it is extended by IO::WaitReadable.
86
* So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
87
*
88
* === See
89
* * TCPServer#accept
90
* * Socket#accept
91
*/
92
static
VALUE
93
tcp_accept_nonblock
(
VALUE
sock)
94
{
95
rb_io_t
*fptr;
96
struct
sockaddr_storage
from;
97
socklen_t fromlen;
98
99
GetOpenFile
(sock, fptr);
100
fromlen = (socklen_t)
sizeof
(from);
101
return
rsock_s_accept_nonblock
(
rb_cTCPSocket
, fptr,
102
(
struct
sockaddr *)&from, &fromlen);
103
}
104
105
/*
106
* call-seq:
107
* tcpserver.sysaccept => file_descriptor
108
*
109
* Returns a file descriptor of a accepted connection.
110
*
111
* TCPServer.open("127.0.0.1", 28561) {|serv|
112
* fd = serv.sysaccept
113
* s = IO.for_fd(fd)
114
* s.puts Time.now
115
* s.close
116
* }
117
*
118
*/
119
static
VALUE
120
tcp_sysaccept
(
VALUE
sock)
121
{
122
rb_io_t
*fptr;
123
struct
sockaddr_storage
from;
124
socklen_t fromlen;
125
126
GetOpenFile
(sock, fptr);
127
fromlen = (socklen_t)
sizeof
(from);
128
return
rsock_s_accept
(0, fptr->
fd
, (
struct
sockaddr*)&from, &fromlen);
129
}
130
131
void
132
rsock_init_tcpserver
(
void
)
133
{
134
/*
135
* Document-class: TCPServer < TCPSocket
136
*
137
* TCPServer represents a TCP/IP server socket.
138
*
139
* A simple TCP server may look like:
140
*
141
* require 'socket'
142
*
143
* server = TCPServer.new 2000 # Server bind to port 2000
144
* loop do
145
* client = server.accept # Wait for a client to connect
146
* client.puts "Hello !"
147
* client.puts "Time is #{Time.now}"
148
* client.close
149
* end
150
*
151
* A more usable server (serving multiple clients):
152
*
153
* require 'socket'
154
*
155
* server = TCPServer.new 2000
156
* loop do
157
* Thread.start(server.accept) do |client|
158
* client.puts "Hello !"
159
* client.puts "Time is #{Time.now}"
160
* client.close
161
* end
162
* end
163
*
164
*/
165
rb_cTCPServer
=
rb_define_class
(
"TCPServer"
,
rb_cTCPSocket
);
166
rb_define_method
(
rb_cTCPServer
,
"accept"
,
tcp_accept
, 0);
167
rb_define_method
(
rb_cTCPServer
,
"accept_nonblock"
,
tcp_accept_nonblock
, 0);
168
rb_define_method
(
rb_cTCPServer
,
"sysaccept"
,
tcp_sysaccept
, 0);
169
rb_define_method
(
rb_cTCPServer
,
"initialize"
,
tcp_svr_init
, -1);
170
rb_define_method
(
rb_cTCPServer
,
"listen"
,
rsock_sock_listen
, 1);
/* in socket.c */
171
}
172
Generated on Fri Nov 22 2013 07:04:07 for Ruby by
1.8.3