to myself 的分类学习日志

做自己想做的事
posts - 232, comments - 6, trackbacks - 0, articles - 0

Socket

Posted on 2010-10-14 00:30 kongkongzi 阅读(329) 评论(0)  编辑 收藏 引用 所属分类: c programming
/* 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, 0sizeof(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, 0sizeof(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, 0sizeof(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;
            }
        }
    }
}


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理