UNP函数笔记六: 基本UDP套接字编程

来源:互联网 发布:平屋面保温层算法 编辑:程序博客网 时间:2024/04/26 15:34

第八章  基本UDP套接字编程:

#include <sys/socket.h>ssize_t recvfrom(int sockfd, void * buff, size_t nbytes, int flags,                  struct sockaddr * from, socklen_t * addrlen);    success return read-bytes(0 means recv a empty package), error return -1    so it is different from tcp-read/recv(0 means get FIN)    since it can use by tcp socketssize_t sendto(int sockfd, const void * buff, size_t nbytes, in flags,                const struct sockaddr * to, socklen_t addrlen);    success return write-bytes, error return -1    we can send a empty package(0 bytes)    it can use by tcp socket

示例:

#ifndef __ERROR_EXIT_H__#define __ERROR_EXIT_H__#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>void err_exit(const char * msg){    printf("%s: %s\n", msg, strerror(errno));    exit(1);}#endif

#include <netinet/in.h>#include <sys/socket.h>#include "dg_echo.h"#include "err_exit.h"#define SERV_PORT 34567int main(int argc, char * argv[]){    int                 sockfd;    struct sockaddr_in  servaddr;    struct sockaddr_in  cliaddr;    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {        err_exit("socket error");    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family      = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port        = htons(SERV_PORT);    if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        err_exit("bind error");    }    dg_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));}

#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#define MAXLINE 4096void dg_echo(int sockfd, struct sockaddr * pcliaddr, socklen_t clilen){    int        n;    socklen_t  len;    char       mesg[MAXLINE];    for ( ; ; ) {        len = clilen;        if ((n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len)) == -1) {            err_exit("recvfrom error");        }        if (sendto(sockfd, mesg, n, 0, pcliaddr, len) == -1) {            err_exit("sendto error");        }    }}

#include <netinet/in.h>#include <sys/socket.h>#include "dg_cli.h"#include "err_exit.h"#define SERV_PORT 34567int main(int argc, char * argv[]){    int                 sockfd;    struct sockaddr_in  servaddr;    if (argc != 2) {        printf("usage: udpcli <IPaddress>\n");        exit(1);    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(SERV_PORT);    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {        err_exit("inet_pton error");    }    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {        err_exit("socket error");    }    dg_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));    exit(0);}

#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#define MAXLINE 4096void dg_cli(FILE * fp, int sockfd, const struct sockaddr * pservaddr,        socklen_t servlen){    int   n;    char  sendline[MAXLINE];    char  recvline[MAXLINE + 1];    while (fgets(sendline, MAXLINE, fp) != NULL) {        if (sendto(sockfd, sendline, strlen(sendline),                    0, pservaddr, servlen) == -1) {            err_exit("sendto error");        }        if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) == -1) {            err_exit("recvfrom error");        }        recvline[n] = 0;  /* null terminate */        if (fputs(recvline, stdout) == EOF) {            err_exit("fputs error");        }    }}

#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#include "sock_ntop.h"#define MAXLINE 4096void dg_cli(FILE * fp, int sockfd, const struct sockaddr * pservaddr,        socklen_t servlen){    int               n;    char              sendline[MAXLINE];    char              recvline[MAXLINE + 1];    char            * paddr;    socklen_t         len;    struct sockaddr * preply_addr;    if ((preply_addr = malloc(servlen)) == NULL) {        err_exit("malloc error");    }    while (fgets(sendline, MAXLINE, fp) != NULL) {        if (sendto(sockfd, sendline, strlen(sendline),                    0, pservaddr, servlen) == -1) {            err_exit("sendto error");        }        len = servlen;        if ((n = recvfrom(sockfd, recvline, MAXLINE,                           0, preply_addr, &len)) == -1) {            err_exit("recvfrom error");        }        /*         * it is not a good idea to use "memcmp"         * cause may sendto-remote-ip and recvfrom-remote-ip is different         * but they are in a same machine         * so we may drop a right response         */        if (len != servlen || memcmp(pservaddr, preply_addr, len) != 0) {            if ((paddr = sock_ntop(preply_addr, len)) == NULL) {                err_exit("sock_ntop error");            }            printf("reply from %s (ignored)\n", paddr);            continue;        }        recvline[n] = 0;  /* null terminate */        if (fputs(recvline, stdout) == EOF) {            err_exit("fputs error");        }    }}

#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#define MAXLINE 4096void dg_cli(FILE * fp, int sockfd, const struct sockaddr * pservaddr,        socklen_t servlen){    int   n;    char  sendline[MAXLINE];    char  recvline[MAXLINE + 1];    if (connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1) {        err_exit("connect error");    }    while (fgets(sendline, MAXLINE, fp) != NULL) {        if (write(sockfd, sendline, strlen(sendline)) == -1) {            err_exit("write error");        }        if ((n = read(sockfd, recvline, MAXLINE)) == -1) {            err_exit("read error");        }        recvline[n] = 0;  /* null terminate */        if (fputs(recvline, stdout) == EOF) {            err_exit("fputs error");        }    }}

#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#define NDG   2000  /* datagrams to send */#define DGLEN 1400  /* length of each datagram */voiddg_cli(FILE * fp, int sockfd, const struct sockaddr * pservaddr,        socklen_t servlen){    int   i;    char  sendline[DGLEN];    for (i = 0; i < NDG; i++) {        if (sendto(sockfd, sendline, DGLEN, 0, pservaddr, servlen) == -1) {            err_exit("sendto error");        }    }}

#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#include "my_signal.h"#define MAXLINE 4096int  count;void recvfrom_int(int signo){    printf("\nreceived %d datagrams\n", count);    exit(0);}void dg_echo(int sockfd, struct sockaddr * pcliaddr, socklen_t clilen){    socklen_t  len;    char       mesg[MAXLINE];    if (my_signal(SIGINT, recvfrom_int) == SIG_ERR) {        err_exit("my_signal error");    }    for ( ; ; ) {        len = clilen;        if (recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len) == -1) {            err_exit("recvfrom error");        }        count++;    }}

#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#include "my_signal.h"#define MAXLINE 4096int  count;void recvfrom_int(int signo){    printf("\nreceived %d datagrams\n", count);    exit(0);}void dg_echo(int sockfd, struct sockaddr * pcliaddr, socklen_t clilen){    int        n;    socklen_t  len;    char       mesg[MAXLINE];    if (my_signal(SIGINT, recvfrom_int) == SIG_ERR) {        err_exit("my_signal error");    }    n = 220 * 1024;    if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1) {        err_exit("setsockopt error");    }    for ( ; ; ) {        len = clilen;        if (recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len) == -1) {            err_exit("recvfrom error");        }        count++;    }}

#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#include "sock_ntop.h"#define SERV_PORT 34567int main(int argc, char * argv[]){    int                  sockfd;    char               * paddr;    socklen_t            len;    struct sockaddr_in   cliaddr;    struct sockaddr_in   servaddr;    if (argc != 2) {        printf("usage: udpcli <IPaddress>\n");        exit(0);    }    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {        err_exit("socket error");    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(SERV_PORT);    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {        err_exit("inet_pton error");    }    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        err_exit("connect error");    }    len = sizeof(cliaddr);    if (getsockname(sockfd, (struct sockaddr *)&cliaddr, &len) == -1) {        err_exit("getsockname error");    }    if ((paddr = sock_ntop((struct sockaddr *)&cliaddr, len)) == NULL) {        err_exit("sock_ntop error");    }    printf("local address %s\n", paddr);    exit(0);}

#include <netinet/in.h>#include <sys/socket.h>#include <sys/select.h>#include <sys/wait.h>#include "str_echo.h"#include "err_exit.h"#include "my_signal.h"#define LISTENQ   1024#define SERV_PORT 34567#define max(a, b)  ((a) >= (b) ? (a) : (b))void sig_chld(int signo){    pid_t  pid;    int    stat;    while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {  /* waitpid + WNOHANG */        printf("child %d terminated\n", pid);    }    return;}int main(int argc, char * argv[]){    int                 listenfd;    int                 connfd;    int                 udpfd;    int                 nready;    int                 maxfdp1;    char                mesg[MAXLINE];    pid_t               childpid;    fd_set              rset;    ssize_t             n;    socklen_t           len;    const int           on = 1;    struct sockaddr_in  cliaddr;    struct sockaddr_in  servaddr;    /* create listening TCP socket */    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {        err_exit("socket SOCK_STREAM error");    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family      = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port        = htons(SERV_PORT);    if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {        err_exit("setsockopt error");    }    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        err_exit("bind error");    }    if (listen(listenfd, LISTENQ) == -1) {        err_exit("listen error");    }    /* create UDP socket */    if ((udpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {        err_exit("socket SOCK_DGRAM error");    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family      = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port        = htons(SERV_PORT);    if (bind(udpfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        err_exit("bind error");    }    if (my_signal(SIGCHLD, sig_chld) == SIG_ERR) {  /* must call waitpid() */        err_exit("my_signal error");    }    FD_ZERO(&rset);    maxfdp1 = max(listenfd, udpfd) + 1;    for ( ; ; ) {        FD_SET(listenfd, &rset);        FD_SET(udpfd, &rset);        if ((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) == -1) {            if (errno == EINTR) {                continue;  /* back to for() */            }            else {                err_exit("select error");            }        }        if (FD_ISSET(listenfd, &rset)) {            len = sizeof(cliaddr);            connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len);            if (connfd == -1) {                err_exit("accept error");            }                if ((childpid = fork()) < 0) {                err_exit("fork error");            }            else if (childpid == 0) {                if (close(listenfd) == -1) {                    err_exit("close listenfd error");                }                str_echo(connfd);  /* process the request */                exit(0);            }            if (close(connfd) == -1) {                err_exit("close connfd error");            }        }        if (FD_ISSET(udpfd, &rset)) {            len = sizeof(cliaddr);            if ((n = recvfrom(udpfd, mesg, MAXLINE, 0,                               (struct sockaddr *)&cliaddr, &len)) == -1) {                err_exit("recvfrom error");            }            if (sendto(udpfd, mesg, n, 0,                        (struct sockaddr *)&cliaddr, len) == -1) {                err_exit("sendto error");            }        }    }}


原创粉丝点击