TCP回射服务器---Unix网络编程笔记

TCP套接字通信流程图
TCP回射客户/服务器

回射服务器程序

#include        "unp.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        "unp.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(SERV_PORT);

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

        Listen(listenfd, LISTENQ);

        for ( ; ; ) {
                clilen = sizeof(cliaddr);
                connfd = Accept(listenfd, (SA *) &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 */
        }
}

回射客户端程序

#include        "unp.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);
        }
}

include        "unp.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(SERV_PORT);
        Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

        Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));

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

        exit(0);
}

正常建立(三次握手)、正常终止(四次挥手)

进程终止之僵死进程

服务器子进程终止时,给父进程发送SIGCHLD信号,服务器进程中没有捕获该信号,而该信号的默认行为是被忽略,因此子进程进入僵死状态。

解决方法:Unix信号处理

POSIX信号处理

信号

信号:“一个进程 或者 内核 ” 告知另一个进程发生了某个事件的通知,也称软件中断。

行为

每个信号都有与之关联的处置,也称行为。可以通过sigaction来设定一个信号的处置:
(1)提供一个函数,每当特定信号发生它就被调用。这种函数称为信号处理函数,这种行为称为捕获信号。SIGKILL和SIGSTOP两种信号不能被捕获。

信号处理函数只有信号值一个参数,没有返回值:
void handler(int signo);
(2)把某个信号的处置设置为SIGIGN来忽略。SIGKILL和SIGSTOP两种信号不能被忽略。
(3)把某个信号的处置设置为SIGDFL来启用它的默认。SIGCHLD和SIDURG两个信号的默认为忽略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值