Socket

/*  client ---- use TCP.  */
#include 
< unistd.h >
#include 
< signal.h >
#include 
< sys / types.h >
#include 
< sys / socket.h >
#include 
< netinet / in .h >    /*  struct sockaddr_in  */
#define  MAXLINE 80
#define  SERV_PORT 8000

void  sig_pipe( int  signo)
{
    
/*  do nothing.  */
}

int  main( int  argc,  char   * argv[])
{
    
struct  sockaddr_in    servaddr;
    
char                 buf[MAXLINE]; 
    
int                     sockfd, n;
    
struct  sigaction    newact;

    newact.sa_handler 
=  sig_pipe;
    sigemptyset(
& newact.sa_mask);
    newact.sa_flags 
=   0 ;
    sigaction(SIGPIPE, 
& newact, NULL);

    sockfd 
=  socket(AF_INET, SOCK_STREAM,  0 );     /

    bzero(
& servaddr,  sizeof (servaddr));
    servaddr.sin_family 
=  AF_INET;
    inet_pton(AF_INET, 
" 127.0.0.1 " & servaddr.sin_addr);
    servaddr.sin_port 
=  htons(SERV_PORT);

    connect(sockfd, (
struct  sockaddr  * & servaddr,  sizeof (servaddr));

    
while  (fgets(buf, MAXLINE, stdin)  !=  NULL) {
        
if  (write(sockfd, buf, strlen(buf))  <   0 ) {
            perror(
" write " );
            exit(
1 );
        }
        n 
=  read(sockfd, buf, MAXLINE);
        
if  (n  ==   0 ) {
            printf(
" the server has been closed.\n " );
            
break ;
        }
        
else
            write(STDOUT_FILENO, buf, n);
    }

    close(sockfd);
    
return   0 ;
}

/*  client ---- use UDP.  */
#include 
< unistd.h >
#include 
< netinet / in .h >

#define  MAXLINE 80
#define  SERV_PORT 8000
int  main( int  argc,  char   * argv[])
{
    
struct  sockaddr_in    servaddr;
    
char                 buf[MAXLINE];
    
int                     sockfd, n;
    socklen_t            servaddr_len;

    sockfd 
=  socket(AF_INET, SOCK_DGRAM,  0 );  /*  different from TCP.  */
    bzero(
& servaddr,  sizeof (servaddr));
    servaddr.sin_family 
=  AF_INET;
    inet_pton(AF_INET, 
" 127.0.0.1 " & servaddr.sin_addr);
    servaddr.sin_port 
=  htons(SERV_PORT);

    
while  (fgets(buf, MAXLINE, stdin)  !=  NULL) {
        n 
=  sendto(sockfd, buf, strlen(buf),  0 , ( struct  sockaddr  * ) & servaddr,
                   
sizeof (servaddr));  /*  different from TCP.  */
        
if  (n  ==   - 1 )
            perr_exit(
" sendto error " );

        n 
=  recvfrom(sockfd, buf, MAXLINE,  0 , NULL,  0 );  /*  different from TCP.  */
        
if  (n  ==   - 1 )
            perr_exit(
" recvfrom error " );
        write(STDOUT_FILENO, buf, n);
    }
    close(sockfd);
    
return   0 ;
}

/*  client ---- use UNIX Domain Socket IPC.  */
#include 
< stddef.h >
#include 
< sys / socket.h >
#include 
< sys / un.h >
int  main( void )
{
    
int  fd, size;
    
struct  sockaddr_un un;

    
if  ((fd  =  socket(AF_UNIX, SOCK_STREAM,  0 ))  <   0 ) {
        perror(
" socket error " );
        exit(
1 );
    }
    un.sun_family 
=  AF_UNIX;
    strcpy(un.sun_path, 
" foo.socket " );
    size 
=  offsetof( struct  sockaddr_un, sun_path)  +  strlen(un.sun_path);

    
if  (bind(fd, ( struct  sockaddr  * ) & un, size)  <   0 ) {
        perror(
" bind error " );
        exit(
1 );
    }
    printf(
" UNIX domain socket bound\n " );
    exit(
0 );
}

#define  CLI_PATH    "/var/tmp"        /* +5 for pid = 14 chars */
/* *
 * Create a client endpoint and connect to a server.
 * Returns fd if all OK, <0 on error.
 
*/
int  cli_conn( const   char   * name)
{
    
int                     fd, len, err, rval;
    
struct  sockaddr_un    un;

    
/*  create a UNIX domain stream socket  */
    
if  ((fd  =  socket(AF_UNIX, SOCK_STREAM,  0 ))  <   0 )
        
return   - 1 ;
    memset(
& un,  0 sizeof (un));
    un.sun_family 
=  AF_UNIX;
    sprintf(un.sun_path, 
" %s%05d " , CLI_PATH, getpid());
    len 
=  offsetof( struct  sockaddr_un, sun_path)  +  strlen(un.sun_path);

    unlink(un.sun_path);        
/*  in case it already exists  */
    
if  (bind(fd, ( struct  sockaddr  * ) & un, len)  <   0 ) {
        rval 
=   - 2 ;
        
goto  errout;
    }
    memset(
& un,  0 sizeof (un));
    un.sun_family 
=  AF_UNIX;
    strcpy(un.sun_path, name);
    len 
=  offsetof( struct  sockaddr_un, sun_path)  +  strlen(name);
    
if  (connect(fd, ( struct  sockaddr  * ) & un, len)  <   0 ) {
        rval 
=   - 4 ;
        
goto  errout;
    }
    
return  fd;
errout:
    err 
=  errno;
    close(fd);
    errno 
=  err;
    
return  rval;
}

/*  server ---- use TCP.  */


/*  server ---- use UDP.  */
#define  MAXLINE 80
#define  SERV_PORT 8000
int  main( void )
{
    
struct  sockaddr_in servaddr, cliaddr;
    socklen_t cliaddr_len;
    
int  sockfd;
    
char  buf[MAXLINE];
    
char  str[INET_ADDRSTRLEN];
    
int  i, n;

    sockfd 
=  Socket(AF_INET, SOCK_DGRAM,  0 );
    bzero(
& servaddr,  sizeof (servaddr));
    servaddr.sin_family 
=  AF_INET;
    servaddr.sin_addr.s_addr 
=  htonl(INADDR_ANY);
    servaddr.sin_port 
=  htons(SERV_PORT);
    Bind(sockfd, (
struct  sockaddr  * ) & servaddr,  sizeof (servaddr));
    printf(
" Accepting connection \n " );
    
while  ( 1 ) {
        cliaddr_len 
=   sizeof (cliaddr);
        n 
=  recvfrom(sockfd, buf, MAXLINE,  0 , ( struct  sockaddr  * ) & cliaddr,  & cliaddr_len);
        
if  (n  ==   - 1 )
            perr_exit(
" recvfrom error " );
        printf(
" received from %s at PORT %d\n "
               inet_ntop(AF_INET, 
& cliaddr.sin_addr, str,  sizeof (str)),
               ntohs(cliaddr.sin_port));
        
for  (i  =   0 ; i  <  n; i ++ )
            buf[i] 
=  toupper(buf[i]);
        n 
=  sendto(sockfd, buf, n,  0 , ( struct  sockaddr  * ) & cliaddr,  sizeof (cliaddr));
        
if  (n  ==   - 1 )
            perr_exit(
" sendto error " );
    }
}

/*  server ---- use UNIX Domain Socket IPC.  */
#include 
< stddef.h >
#include 
< sys / socket.h >
#include 
< sys / un.h >
#include 
< sys / stat.h >
#include 
< errno.h >

#define  QLEN        10

/* *
 * Create a server endpoint of a connection.
 * Returns fd if all OK, <0 on error.
 
*/
int  serv_listen( const   char   * name)
{
    
int  fd, len, err, rval;
    
struct  sockaddr_un un;

    
/*  create a UNIX domain stream socket  */
    
if  ((fd  =  socket(AF_UNIX, SOCK_STREAM,  0 ))  <   0 )
        
return   - 1 ;
    unlink(name);        
/*  in case it already exists  */
    memset(
& un,  0 sizeof (un));
    un.sun_family 
=  AF_UNIX;
    strcpy(un.sun_path, name);
    len 
=  offsetof( struct  sockaddr_un, sun_path)  +  strlen(name);

    
/*  bind the name to the descriptor  */
    
if  (bind(fd, ( struct  sockaddr  * ) & un, len)  <   0 ) {
        rval 
=   - 2 ;
        
goto  errout;
    }
    
if  (listen(fd, QLEN)  <   0 ) {  /*  tell kernel we're a server  */
        rval 
=   - 3 ;
        
goto  errout;
    }
    
return  fd;
errout:
    err 
=  errno;
    close(fd);
    errno 
=  err;
    
return  rval;
}
int  serv_accept( int  listenfd, uid_t  * uidptr)
{
    
int                     clifd, len, err, rval;
    time_t                staletime;
    
struct  sockaddr_un    un;
    
struct  stat            statbuf;

    len 
=   sizeof (un);
    
if  ((clifd  =  accept(listenfd, ( struct  sockaddr  * ) & un,  & len))  <   0 )
        
return   - 1 ;             /*  often errno = EINTR, if signal caught  */

    
/*  obtain the client's uid from its calling address  */
    len 
-=  offsetof( struct  sockaddr_un, sun_path);
    un.sun_path[len] 
=   0 ;

    
if  (stat(un.sun_path,  & statbuf)  <   0 ) {
        rval 
=   - 2 ;
        
goto  errout;
    }
    
if  (S_ISSOCK(statbuf.st_mode)  ==   0 ) {
        rval 
=   - 3 ;
        
goto  errout;
    }
    
if  (uidptr  !=  NULL)
        
* uidptr  =  statbuf.st_uid;     /*  return uid of caller  */
    unlink(un.sun_path);
    
return  clifd;
errout:
    err 
=  errno;
    close(clifd);
    errno 
=  err;
    
return  rval;
}

/*  implement concurrent service.  */
/*  #1, use fork().  */
#define  MAXLINE 80
#define  SERV_PORT 8000
void  sig_chld( int  signo)
{
    pid_t pid;
    
int  status;

    pid 
=  wait( & status);
    printf(
" subprocess %d exit at %d\n " , pid, status);
}
int  main( void )
{
    
struct  sockaddr_in    servaddr, cliaddr;
    socklen_t            cliaddr_len;
    
int                     listenfd, connfd;
    
char                 buf[MAXLINE];
    
char                 str[INET_ADDRSTRLEN];
    
int                     i, n;
    
int                     opt  =   1 ;
    pid_t                pid;
    
struct  sigaction    act;

    act.sa_handler 
=  sig_chld;
    sigemptyset(
& act.sa_mask);
    act.sa_flags 
=   0 ;
    sigaction(SIGCHLD, 
& act, NULL);
    
    listenfd 
=  Socket(AF_INET, SOCK_STREAM,  0 );
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, 
& opt,  sizeof (opt));
    bzero(
& servaddr,  sizeof (servaddr));
    servaddr.sin_family 
=  AF_INET;
    servaddr.sin_addr.s_addr 
=  htonl(INADDR_ANY);
    servaddr.sin_port 
=  htons(SERV_PORT);
    Bind(listenfd, (
struct  sockaddr  * ) & servaddr,  sizeof (servaddr));
    Listen(listenfd, 
20 );
    printf(
" Accepting connection \n " );
    
while  ( 1 ) {
        cliaddr_len 
=   sizeof (cliaddr);
        connfd 
=  Accept(listenfd, 
                        (
struct  sockaddr  * ) & cliaddr,  & cliaddr_len);
        pid 
=  fork();
        
if  (pid  ==   - 1 ) {
            perror(
" call to fork " );
            exit(
1 );
        } 
else   if  (pid  ==   0 ) {
            close(listenfd);
            
while  ( 1 ) {
                n 
=  Read(connfd, buf, MAXLINE);
                
if  (n  ==   0 ) {
                    printf(
" the client has been closed.\n " );
                    
break ;
                }
                printf(
" received from %s at PORT %d\n " ,
                       inet_ntop(AF_INET, 
& cliaddr.sin_addr, str, 
                                 
sizeof (str)),ntohs(cliaddr.sin_port));
                
for  (i  =   0 ; i  <  n; i ++ )
                    buf[i] 
=  toupper(buf[i]);
                Write(connfd, buf, n);
            }
            Close(connfd);
            exit(
0 );
        } 
else  {
            close(connfd);
        }    
    }
}
/*  #2, use select().  */
#define  MAXLINE 80
#define  SERV_PORT 8000
int  main( int  argc,  char   * argv[])
{
    
int  i, maxi, maxfd, listenfd, connfd, sockfd;
    
int  nready, client[FD_SETSIZE];
    ssize_t n;
    fd_set rset, allset;
    
char  buf[MAXLINE];
    
char  str[INET_ADDRSTRLEN];
    socklen_t cliaddr_len;
    
struct  sockaddr_in cliaddr, servaddr;

    listenfd 
=  Socket(AF_INET, SOCK_STREAM,  0 );

    bzero(
& servaddr,  sizeof (servaddr));
    servaddr.sin_family 
=  AF_INET;
    servaddr.sin_addr.s_addr 
=  htonl(INADDR_ANY);
    servaddr.sin_port 
=  htons(SERV_PORT);

    Bind(listenfd, (
struct  sockaddr  * ) & servaddr,  sizeof (servaddr));

    Listen(listenfd, 
20 );

    maxfd 
=  listenfd;
    maxi 
=   - 1 ;
    
for  (i  =   0 ; i  <  FD_SETSIZE; i ++ )
        client[i] 
=   - 1 ;
    FD_ZERO(
& allset);
    FD_SET(listenfd, 
& allset);

    
for  (;;) {
        rset 
=  allset;
        nready 
=  select(maxfd  +   1 & rset, NULL, NULL, NULL);
        
if  (nready  <   0 )
            perr_exit(
" select error " );

        
if  (FD_ISSET(listenfd,  & rset)) {
            cliaddr_len 
=   sizeof (cliaddr);
            connfd 
=  Accept(listenfd, 
                            (
struct  sockaddr  * ) & cliaddr,  & cliaddr_len);
            printf(
" received from %s at PORT %d\n " ,
                   inet_ntop(AF_INET, 
& cliaddr.sin_addr, str,  sizeof (str)),
                   ntohs(cliaddr.sin_port));
            
for  (i  =   0 ; i  <  FD_SETSIZE; i ++ )
                
if  (client[i]  <   0 ) {
                    client[i] 
=  connfd;
                    
break ;
                }
            
if  (i  ==  FD_SETSIZE) {
                fputs(
" too many clients\n " , stderr);
                exit(
1 );
            }
            FD_SET(connfd, 
& allset);
            
if  (connfd  >  maxfd)
                maxfd 
=  connfd;
            
if  (i  >  maxi)
                maxi 
=  i;
            
if  ( -- nready  <=   0 )
                
continue ;
        }
        
for  (i  =   0 ; i  <=  maxi; i ++ ) {
            
if  ((sockfd  =  client[i])  <   0 )
                
continue ;
            
if  (FD_ISSET(sockfd,  & rset)) {
                
if  ((n  =  Read(sockfd, buf, MAXLINE))  ==   0 ) {
                    Close(sockfd);
                    FD_CLR(sockfd, 
& allset);
                    client[i] 
=   - 1 ;
                } 
else  {
                    
int  j;
                    
for  (j  =   0 ; j  <  n; j ++ )
                        buf[j] 
=  toupper(buf[j]);
                    Write(sockfd, buf, n);
                }
                
if  ( -- nready  <=   0 )
                    
break ;
            }
        }
    }
}

你可能感兴趣的:(Socket)