UNIX网络编程卷一:第一章 简单的客户端服务器程序

// 从服务器读取时间


// client.c


#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>  
#include <stdlib.h>        // exit
#include <netinet/in.h> // socketaddr_in 
#include <strings.h>    // bzero
#include <arpa/inet.h>    // inet_pton
#include <unistd.h>        // read

#define    MAXLINE        4096    /* max text line length */
#define PORT 8888

int main(int argc, char ** argv)
{
    int sockfd, n;
    char recvline[MAXLINE + 1];
    struct sockaddr_in servaddr;

    if (argc != 2) {
       fprintf(stderr, "Usage: %s IP\n", argv[0]);
       exit(1);
    }

    // 创建套接字 
    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
       fprintf(stderr, "socket error\n");
       exit(1);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(PORT);  // 端口号使用网络字节序
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <=0) {// 将ip地址由字符串,转换位2进制
        fprintf(stderr, "inet_pton error for: %s", argv[1]);
        exit(1);
    }

    // 连接服务器, 后续使用该套接字进行通信
    if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
        fprintf(stderr, "connect error: %s\n", argv[1]);
        perror("connect error:");
        exit(1);
    }

    // 与服务器进行通信
    while( (n = read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = 0;
        if (fputs(recvline, stdout) == EOF) {
            fprintf(stderr, "fputs error\n");
            exit(1);
        }
    }

    if(n < 0) {
        fprintf(stderr, "read error\n");
        exit(1);
    }
    

    return 0;
}


// server.c

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>  
#include <stdlib.h>     // exit
#include <netinet/in.h> // socketaddr_in 
#include <strings.h>    // bzero
#include <arpa/inet.h>  // inet_pton
#include <unistd.h>     // read
#include <time.h>       // time
#include <string.h>     // strlen

#define	MAXLINE		4096	/* max text line length */
#define PORT    8888

int main(int argc, char ** argv)
{
    struct sockaddr_in servaddr;
    int listenfd, connfd;
    char buff[MAXLINE];
    time_t ticks;


    // 创建套接字
    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    // INADDR_ANY : 如果服务器有多个网络接口,那么服务器可以在任意网络接口上接受客户连接
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr.sin_port = htons(PORT);

    // 将该套接字与地址绑定
    bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

    // 把该套接字,变成监听套接字
    // 这样,来自客户到外来连接就可以在该套接字上由内核接受
    // socket, bind, listen 是TCP服务器准备“监听套接字” 的正常步骤
    listen(listenfd, 5);

    for(;;) {
        // 服务器睡眠,等待客户端连接
        // 经过 TCP 3次握手
        // 返回一个 “已连接描述符”
        connfd = accept(listenfd, (struct sockaddr *) NULL, NULL);

        // 发送时间给客户端
        ticks = time(NULL);
        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
        write(connfd, buff, strlen(buff));

        // 关闭连接
        close(connfd);
    }


    return 0;
}




遇到的问题

error: storage size of ‘servaddr’ isn’t known struct sockaddr_in servaddr;    

添加头文件: netinet/in.h    

#include <netinet/in.h>

see $ man 7 ip for more help


你可能感兴趣的:(UNIX网络编程卷一:第一章 简单的客户端服务器程序)