Pro_1_UNIX下最简单的C_S程序_2016_8_5

来源:互联网 发布:java 读取磁盘 io 编辑:程序博客网 时间:2024/06/10 08:57


service:

/* * 抄自《UNIX网络编程:卷1》, 稍作修改。 * 仅仅用于学习目的。学无止境,进步每一天。 *   * slickedit编辑。  *   * 254008829@qq.com  *   */#include <stdio.h>#include <stdlib.h> /* exit */ #include <string.h> /* bzero */#include <unistd.h> /* read */#include <netinet/in.h> /* strut sockaddr_in */#include <arpa/inet.h>  /* inet_pton */#include <time.h>#include <errno.h> /* errno */#defineMAXLINE 65507#define LISTEN_MAX 10#define FUNC_RET(func, val) \    do { \        int rv; \        if ( (rv=func) < 0) { \            printf("LINE = %d, error str: %s\n", __LINE__, strerror(errno)); \            exit(-1); \        } \        val = rv; \    } while (0);int main(int argc, char **argv){    int sockfd, connfd, ret;    char buf[MAXLINE];    struct sockaddr_in servaddr;    FUNC_RET(socket(AF_INET, SOCK_STREAM, 0), sockfd);    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(13);    /* INADDR_ANY,当服务器有多个网络接口的时候, 服务器可以从任意网络接口上接收来自客服端的消息 */    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    /* 将生成的sockfd与设置的servaddr绑定 */    FUNC_RET(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)), ret);    /* listen把该套接字转化成一个监听套接字 */    FUNC_RET(listen(sockfd, LISTEN_MAX), ret);    while (1) {        time_t ticks;        /* accept函数执行后服务进程会陷入睡眠,等待某个客户端连接,并被内核接受, 唤醒进程。         TCP连接使用的是三次握手, 握手完成后accept返回, 它返回的是新的描述符。称之为已连接描述符,        服务端用这个新的connfd与新近连接的那个客户程序通信 */        FUNC_RET(accept(sockfd, (struct sockaddr *)NULL, NULL), connfd);        ticks = time(NULL);        snprintf(buf, sizeof(buf), "%.24s\r\n", ctime(&ticks));        write(connfd, buf, strlen(buf));        close(connfd);    }    exit(0);}/*在ubuntu下编译: gcc daytimetcpserv.c -o service 运行: sudo ./service  */

client:

/* * 抄自《UNIX网络编程:卷1》  * 仅仅用于学习目的   *   * slickedit编辑。  *   * 254008829@qq.com  *   */#include <stdio.h>#include <stdlib.h> /* exit */ #include <string.h> /* bzero */#include <unistd.h> /* read */#include <netinet/in.h> /* strut sockaddr_in */#include <arpa/inet.h>  /* inet_pton */#include <errno.h> /* errno */#defineMAXLINE 65507#define FUNC_RET(func, val) \    do { \        int rv; \        if ( (rv=func) < 0) { \            printf("LINE = %d, error str: %s\n", __LINE__, strerror(errno)); \            perror("FUNC_RET"); \            exit(-1); \        } \        val = rv; \    } while (0);int main(int argc, char **argv){    int sockfd, n, ret;    char recvline[MAXLINE + 1];    struct sockaddr_in servaddr;    if (argc != 2) {        printf("usage: %s ip_addr\n", argv[0]);        exit(0);    }    /*     * socket函数是创建一个socket套接字,第一个参数是AF_INET表明是IPV4协议, SOCK_STREAM表明是传送的是字节流。      * 第三个参数为零, 则默认AF_INET和SOCK_STREAM组合是TCP协议。      */    FUNC_RET(socket(AF_INET, SOCK_STREAM, 0), sockfd);    bzero(&servaddr, sizeof(servaddr)); // 将auto变量servaddr清零。    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(13); // 13是时间获取服务器众所周知的端口。    /* 将十进制点分式的IP地址转换成网络格式 */    FUNC_RET(inet_pton(AF_INET, argv[1], &servaddr.sin_addr), ret);    /* connect函数应用于TCP套接字时候, 将sockfd与servaddr结构指定的服务器建立一个TCP连接 */    FUNC_RET(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)), ret);    /* 从连接的服务器处读取内容 */    while ( (n=read(sockfd, recvline, MAXLINE)) > 0) {        recvline[n] = 0;        if (fputs(recvline, stdout) == EOF) {            perror("fputs error:");            exit(0);        }    }    if (n < 0) {        perror("read error: ");    }    exit(0);}/*在ubuntu下编译生成client可执行文件。 等服务端先运行后,执行: ./client 127.0.0.1 结果为:     Sun Aug  7 11:33:42 2016 127.0.0.1这个IP是本地回环IP, client程序连接这个IP表明是和自己本机通信。  */





0 0
原创粉丝点击