Reference: http://blog.csdn.net/andyxie407/article/details/1672325
Today, I encountered a lot of problems running on the 16-14 (client) and 16-15 (server) In chapter 16th of apue, run the method thanks to the andyxie407 article for a good reference (originally the same, not for reference), but still cannot run the results, the results found the wrong place of the two programs (forgive me, sometimes, I think the code will be knocked out at a glance.) I write it all here, and I will show the painful running results. The Code is as follows:
[CPP]View plaincopy
- // 16-14.c is the client
- # Include "apue. H"
- # Include <netdb. h>
- # Include <errno. h>
- # Include <sys/socket. h>
- # Define maxaddrlen 256
- # Define buflen 128
- # Define maxsllep 128
- Int connect_retry (INT sockfd, struct sockaddr * ADDR, socklen_t Alen)
- {
- Int nsec;
- For (nsec = 1; nsec <maxsllep; nsec <= 1) {// nsec <= 1 equal to nsec = nsec <1 equal to nsec/= 2;
- If (connect (sockfd, ADDR, Alen) = 0)
- Return 0;
- If (nsec <= maxsllep/2)
- Sleep (nsec );
- }
- Return-1;
- }
- Void print_uptime (INT sockfd)
- {
- Char Buf [buflen];
- Int N;
- While (n = Recv (sockfd, Buf, buflen, 0)> 0)
- Write (stdout_fileno, Buf, N );
- If (n <0)
- Err_sys ("Recv error ");
- }
- Int main (INT argc, char * argv [])
- {
- Struct addrinfo * AIP, * ailist;
- Struct addrinfo hint;
- Int err, sockfd;
- If (argc! = 2)
- Err_quit ("Usage: ruptime hostname ");
- Hint. ai_family = 0;
- Hint. ai_flags = 0; // ai_canonname;
- Hint. ai_socktype = sock_stream;
- Hint. ai_protocol = 0;
- Hint. ai_addrlen = 0;
- Hint. ai_canonname = NULL;
- Hint. ai_addr = NULL;
- Hint. ai_next = NULL;
- If (ERR = getaddrinfo (argv [1], "ruptime", & hint, & ailist ))! = 0)
- Err_quit ("getaddrinfo: % s", gai_strerror (ERR ));
- For (AIP = ailist; AIP! = NULL; AIP = AIP-> ai_next ){
- If (sockfd = socket (AIP-> ai_family, sock_stream, 0) <0 ){
- Err = errno;
- }
- If (connect_retry (sockfd, AIP-> ai_addr, AIP-> ai_addrlen) <0)
- Err = errno;
- Else {
- Printf ("connect to ruptime server successfully! \ N ");
- Print_uptime (sockfd );
- Exit (0 );
- }
- }
- Fprintf (stderr, "cannot connect to % s: % s \ n", argv [1], strerror (ERR ));
- Exit (1); // err happened
- }
[CPP]View plaincopy
- // 16-15.c is the server
- # Include "apue. H"
- # Include <netdb. h>
- # Include <syslog. h>
- # Include <errno. h>
- # Include <sys/socket. h>
- # Define buflen 128
- # Define qlen 10
- # Ifndef host_name_max
- # Define host_name_max 256
- # Endif
- Int init_server (INT type, struct sockaddr * ADDR, socklen_t Alen, int qlen)
- {
- Int FD, err = 0;
- If (FD = socket (ADDR-> sa_family, type, 0) <0)
- Return-1;
- If (BIND (FD, ADDR, Alen) <0 ){
- Err = errno;
- Goto errout;
- }
- If (type = sock_stream | type = sock_seqpacket ){
- If (Listen (FD, qlen) <0 ){
- Err = errno;
- Goto errout;
- }
- }
- Return FD; // successful when prog arrive here.
- Errout:
- Close (FD); // exit with failuare
- Errno = err;
- Return-1;
- }
- Void serve (int fd)
- {
- Char Buf [buflen];
- Int clfd;
- File * FP;
- For (;;){
- If (clfd = accept (FD, null, null) <0 ){
- Syslog (log_err, "ruptime: accept error: % s", strerror (errno ));
- Exit (1 );
- }
- If (FP = popen ("/usr/bin/uptime", "R") = NULL ){
- Sprintf (BUF, "error: % s \ n", strerror (errno ));
- Send (clfd, Buf, strlen (BUF), 0 );
- } Else {
- While (fgets (BUF, buflen, FP )! = NULL)
- Send (clfd, Buf, strlen (BUF), 0 );
- Pclose (FP );
- }
- Close (clfd); // send end
- }
- }
- Int main (INT argc, char * argv [])
- {
- Struct addrinfo * ailist, * AIP;
- Struct addrinfo hint;
- Int err, sockfd, N;
- Char * Host;
- If (argc! = 1)
- Err_quit ("Usage: Service ");
- # Ifdef _ SC _host_name_max
- N = sysconf (_ SC _host_name_max );
- If (n <0)
- # Endif
- N = host_name_max;
- Host = malloc (N );
- If (! Host)
- Err_sys ("malloc error ");
- If (gethostname (host, n) <0)
- Err_sys ("gethostname ");
- Printf ("host name is: % s \ n", host );
- Daemonize ("ruptimed ");
- Hint. ai_flags = ai_canonname;
- Hint. ai_family = 0;
- Hint. ai_socktype = sock_stream;
- Hint. ai_protocol = 0;
- Hint. ai_addrlen = 0;
- Hint. ai_canonname = NULL;
- Hint. ai_addr = NULL;
- Hint. ai_next = NULL;
- If (ERR = getaddrinfo (host, "ruptime", & hint, & ailist ))! = 0 ){
- Syslog (log_err, "ruptime: getaddrinfo error: % s", gai_strerror (ERR ));
- Exit (1 );
- }
- For (AIP = ailist; AIP! = NULL; AIP = AIP-> ai_next ){
- Sockfd = init_server (sock_stream, AIP-> ai_addr, AIP-> ai_addrlen, qlen );
- If (sockfd> = 0 ){
- Serve (sockfd );
- Exit (0 );
- }
- }
- Exit (1 );
- }
Compile the file into an executable file, and then run the server./ruptimed. You can see the error through/var/log/syslog.
Servname not supported for ai_socktype.
Solution: First Add the following content to/etc/services:
Ruptime 4000/tcp
Save and exit, but make sure that port 4000 is not occupied by other services. Otherwise, use another port. Run
$./Ruptimed
This is the name compiled in 16-15. You can see through PS-EF that the program has become a background program and then run it.
$./Ruptime Ubuntu
The previous one is the name compiled in 16-14, and the later one is the user/Host Name (as mentioned in the previous article, but localhost or 127.0.0.1 cannot be used here
The result is displayed.
12:06:45 up, 2 users, load average: 0.00, 0.01, 0.05
Very excited!
You do not need to change/etc/services. You need to change the service name in the program to the port number and then modify other content. For more information, see references!
By the way, remind yourself that when you cannot ensure the correctness of your program (even if the program is compiled, it cannot indicate that there is no error or something missing), do not look for any reason other than the program, remember!
Example of running in chapter 16 of apue16-14