《UNIX網絡編程》TCP客戶端服務器例子

最近在看《UNIX網絡編程》(簡稱unp)和《Linux程序設計》,對於unp中第一個獲取服務器時間的例子,實踐起來老是有點頭痛的,由於做者將聲明所有包含在了unp.h裏,致使後面編寫代碼會對這個頭文件形成依賴,而學習不到調用了相應功能以後,應該包含哪些確切的頭文件。編程

再者,我下載了unp.h以後,頭文件包含再次產生了其餘的依賴缺失,所以便參考了《Linux程序設計》中socket一章的入門例子的頭文件包含,而且編譯中仍然找不到的包含或者是宏定義在unp.h中搜索並粘貼進來,從而不須要再包含相似unp.h之類的自定義頭文件。服務器

 

如下代碼在root權限下運行,由於使用的端口號13對於非root用戶可能會無權訪問。網絡

 

unp原書中服務器獲取機器時間送回客戶端,但我在運行中,字符串保存到buffer區的函數snprintf()老是形成了內存錯誤而中斷,因此本着入門的目的,改成了複製一句話到buffer中。socket

 

/*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":this

1 $ ./client 127.0.0.1
相關文章
相關標籤/搜索