《UNIX网络编程》TCP客户端服务器例子

最近在看《UNIX网络编程》(简称unp)和《Linux程序设计》,对于unp中第一个获取服务器时间的例子,实践起来总是有点头痛的,因为作者将声明全部包含在了unp.h里,导致后面编写代码会对这个头文件造成依赖,而学习不到调用了相应功能之后,应该包含哪些确切的头文件。

再者,我下载了unp.h之后,头文件包含再次产生了其他的依赖缺失,因此便参考了《Linux程序设计》中socket一章的入门例子的头文件包含,并且编译中仍然找不到的包含或者是宏定义在unp.h中搜索并粘贴进来,从而不需要再包含类似unp.h之类的自定义头文件。

 

以下代码在root权限下运行,因为使用的端口号13对于非root用户可能会无权访问。

 

unp原书中服务器获取机器时间送回客户端,但我在运行中,字符串保存到buffer区的函数snprintf()总是造成了内存错误而中断,所以本着入门的目的,改为了复制一句话到buffer中。

 

/*client.c*/

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <sys/un.h>

#include <unistd.h>

#include <stdlib.h>



#include <netinet/in.h>



#define MAXLINE 4096

#define PORT 13

#define    SA    struct sockaddr



int main(int argc, char *argv[])

{

    int sockfd, n;

    char recvline[MAXLINE+1];

    struct sockaddr_in servaddr;



    if (argc != 2) {

        fprintf(stderr, "usage: client <IP>\n");

        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) {

        fprintf(stderr, "inet_pton error for %s\n", argv[1]);

        exit(1);

    }



    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) {

        fprintf(stderr, "connect error\n");

        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);

    }



    exit(0);

}

 

/*server.c*/

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <sys/un.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <netinet/in.h>



#define MAXLINE 4096

#define    LISTENQ 1024

#define PORT 13

#define SA  struct sockaddr



int main(int argc, char *argv[])

{

    int listenfd, connfd;

    struct sockaddr_in servaddr;

    char buff[MAXLINE+1];

    time_t t;



    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(PORT);



    bind(listenfd, (SA *) &servaddr, sizeof(servaddr));



    listen(listenfd, LISTENQ);



    while (1) {

        connfd = accept(listenfd, (SA *)NULL, NULL);



        /* write something to buff[]*/

        strcpy(buff, "this is a message\n");



        write(connfd, buff, strlen(buff));

        close(connfd);

    }



    exit(0);

}

 

编译文件:

1 $ gcc client.c -o client

2 $ gcc server.c -o server

在一个窗口中运行服务器:

1 $ ./server

在另一个窗口运行客户端,从而显示出一句话"this is a message":

1 $ ./client 127.0.0.1

 

你可能感兴趣的:(unix)