您的位置:首页 > 理论基础 > 计算机网络

TCP 客户/服务器程序示例

2014-03-05 10:20 246 查看
(UNP 第五章)

Server端:

#include "util.h"

int
main(int argc, char **argv)
{
        int                                     listenfd, connfd;
        pid_t                           childpid;
        socklen_t                       clilen;
        struct sockaddr_in      cliaddr, servaddr;

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

        Bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

        Listen(listenfd,1024 );

        for ( ; ; ) {
                clilen = sizeof(cliaddr);
                connfd = Accept(listenfd, (struct sockaddr  *) &cliaddr, &clilen);

                if ( (childpid = Fork()) == 0) {        /* child process */
                        Close(listenfd);        /* close listening socket */
                        str_echo(connfd);       /* process the request */
                        exit(0);
                }
                Close(connfd);                  /* parent closes connected socket */
        }
}


str_echo()函数:

#include "util.h"

void
str_echo(int sockfd)
{
        ssize_t n;
        char    buf[MAXLINE];

again:
        while ( (n = read(sockfd, buf, MAXLINE)) > 0)
                Writen(sockfd, buf, n);

        if (n < 0 && errno == EINTR)
                goto again;
        else if (n < 0)
                err_sys("str_echo: read error");
}


客户端:

#include "util.h"

int
main(int argc, char **argv)
{
        int sockfd;
        struct sockaddr_in      servaddr;

        if (argc != 2)
                err_quit("usage: tcpcli <IPaddress>");

        sockfd = Socket(AF_INET, SOCK_STREAM, 0);

        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(1234);
        Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

        Connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

        str_cli(stdin, sockfd);         /* do it all */

        exit(0);
}

这里的问题是:当服务器进程终止,客户端没有察觉套接字上的问题,会阻塞于fgets函数,而不会提前退出。

str_cli()函数:

#include "util.h"

void
str_cli(FILE *fp, int sockfd)
{
        char    sendline[MAXLINE], recvline[MAXLINE];

        while (Fgets(sendline, MAXLINE, fp) != NULL) {

                Writen(sockfd, sendline, strlen(sendline));

                if (Readline(sockfd, recvline, MAXLINE) == 0)
                        err_quit("str_cli: server terminated prematurely");

                Fputs(recvline, stdout);
        }
}


其他的都是包裹函数。

Makefile文件:

default:tcpserver tcpclient

tcpserver:tcpserver01.o wrapsock.o str_echo.o writen.o util.h error.o wrapunix.o
        cc -o tcpserver tcpserver01.o wrapsock.o str_echo.o writen.o error.o wrapunix.o
tcpserver01.o:tcpserver01.c util.h
        cc -c tcpserver01.c
wrapsock.o:wrapsock.c util.h
        cc -c wrapsock.c

tcpclient:tcpcli01.o wrapsock.o writen.o str_cli.o util.h error.o wrapunix.o wrapstdio.o readline.o
        cc -o tcpclient tcpcli01.o wrapsock.o  writen.o str_cli.o error.o wrapunix.o wrapstdio.o readline.o

clean:
        rm -f *.o tcpserver tcpclient
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: