| Prev | Index | Next |
Function inetsocket creates a socket but, unlike
tcpconnect, does not connect it. Here's the prototype:
int inetsocket(int type, int_16 port);or
int inetsocket(int type, int_16 port, u_int32_t addr);
inetsocket does bind the socket to the
specified port and address. type should be
SOCK_STREAM for a TCP socket and SOCK_DGRAM
for a UDP socket. (The optional addr parameter is to
make the socket available on a specific local interface only.) Note
that inetsocket does not put the socket in non-blocking
mode. You have to call libasync's make_async to make it
non-blocking.
What follows is an example of an echo-server, i.e., a server that writes back to the client whatever it reads from the client. Notice that most of the code is remarkably similar to the HTTP client from the previous lesson.
1: #include "async.h"
2:
3: void
4: echo_write(int fd, strbuf buf)
5: {
6: int n = buf.tosuio()->output(fd);
7:
8: if(n < 0)
9: fatal << "write\n";
10:
11: // still stuff to write: don't disable writability callback
12: if(buf.tosuio()->resid())
13: return;
14:
15: fdcb(fd, selwrite, 0);
16: }
17:
18:
19:
20: void
21: echo_read(int fd)
22: {
23: strbuf buf;
24: int n = buf.tosuio()->input(fd);
25:
26: if(n < 0)
27: fatal << "read\n";
28:
29: if(n == 0) {
30: fdcb(fd, selread, 0);
31: close(fd);
32: return;
33: };
34:
35: fdcb(fd, selwrite, wrap(echo_write, fd, buf));
36: }
37:
38: void
39: accept_connection(int fd)
40: {
41: struct sockaddr_in sin;
42: unsigned sinlen = sizeof(sin);
43:
44: int cs = accept(fd, (struct sockaddr *) &sin, &sinlen);
45: if (cs >= 0) {
46: warn << "accepted connection. file descriptor = " << cs << "\n";
47: } else if (errno != EAGAIN)
48: fatal << "accept; errno = " << errno << "\n";
49:
50: fdcb(cs, selread, wrap(echo_read, cs));
51: }
52:
53:
54: int
55: main(int argc, char *argv[])
56: {
57: if(argc < 2)
58: fatal << "usage: inetsocket port\n";
59:
60: int fd = inetsocket(SOCK_STREAM, atoi(argv[1]));
61: if (fd < 0)
62: fatal << "inetsocket\n";
63: make_async(fd);
64: if (listen(fd, 5) < 0)
65: fatal << "listen\n";
66:
67: fdcb(fd, selread, wrap(accept_connection, fd));
68:
69: amain();
70: }
Line 24 creates a new socket bound to port 2206. The call to
make_async on line 27 puts the socket in non-blocking
mode. listen causes the socket to wait for incoming
connections. The call to fdcb on line 31 tells libasync
to call accept_connection when someone tries to connect
to the server we just spun off.
accept_connection accepts client connections by
calling accept, prints out a message, and then terminates
the program properly.
more explanation comes here...
| Prev | Index | Next |