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 |