• UNP学习第四章tcp


    一、TCP简单流程图

    因为对于server我已经写过一篇笔记了:http://www.cnblogs.com/ch122633/p/8315883.html

     所以我想再补充一些对于client的部分的笔记、和fork相关的总结。

    二、connect函数:

    #include <sys/socket.h>
    
    int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
    返回:0成功,-1出错
    sockfd:套接字描述符
    servaddr:套接口地址结构的指针
    addrlen:该结构大小

    客户在调用connect不必非调用bind,内核会选择源IP和临时端口。

    connect函数会激发TCP三路握手过程,且仅在连接建立成功或出错时才返回。

    bind函数:

    #include <sys/socket.h>
    
    int bind(int sockfd, const struct sockaddr *myaddr, sockelt_t addrlen);
    返回:0成功,-1出错

    listen函数

    #include <sys/socket.h>
    
    int listen(int sockfd, int backlog);
    返回:0成功,-1出错

    accept函数

    #include <sys/socket.h>
    
    int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
    返回:非负描述字OK,-1出错

    三、fork和exec函数

    #include <unistd.h>
    
    pid_t fork(void);
    返回:在子进程中为0,在父进程中为子进程ID,-1出错

    fork有两个典型应用:

    1.进程创建自己的一个拷贝,当拷贝处理一个操作时,其他的拷贝可以执行其他任务。(网络)

    2.一个进程想执行其他程序,犹豫创建新进程的唯一方法是调用fork,然后调用exec执行新程序。(shell)

    #include <unistd.h>
    
    int execl(const char *pathname, const char *arg0, ... /* (char *)0 */);
    int execv(const char *pathname, char *const argv[]);
    int execle(const char *pathname, const char *arg0, ...
                    /* (char *)0, char *const envp[] */);
    int execve(const char *pathname, char *const argv[], char *const envp[]);
    int execlp(const char *filename, const char *arg0, ... /* (char *)0 */);
    int execvp(const char *filename, char *const argv[]);
    返回:-1出错,无返回成功

    四、并发服务器

    迭代服务器:大多数UDP服务器时迭代服务器,被单个客户长时间占用。

    并发服务器:TCP服务器多使用,能同时服务多个客户。

        pid_t pid;
        int listenfd, connfd;
    
        listenfd = Socket(...);
            /* fill in sockaddr_in{} with server's well-known port */
        Bind(listenfd, ...);
        Listen(listenfd, LISTENQ);
        for(; ;) {
            connfd = Accept(listenfd, ...);             /* probably blocks */
            if((pid = Fork()) == 0) {
                Close(listenfd);                        /* child closes listening socket */
                doit(connfd);                           /* process the request */
                Close(connfd);                          /* done with this client */
                exit(0);                                /* child terminates */
            }
            Close(connfd);                              /* parent closes connected socket */
        }

    在服务器阻塞于accept调用、连接请求从客户到达时客户和服务器的状态。

    从accept返回后,连接被内核接受,新的套接口即connfd被创建,这是一个已连接套接口,可由此通过连接读、写数据。

    并发服务器下一步是调用fork,此时listenfd和connfd都是在父进程和子进程共享的。

    一般套接口也用close关闭,终止TCP连接

    #include <unistd.h>
    
    int close(int sockfd);
    返回:0成功,-1出错

    五、getsockname和getpeername函数

    #include <sys/socket.h>
    
    int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);
    int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);
    返回:0成功,-1出错

    getsockname返回套接口关联的本地协议地址

    getpeername返回套接口关联的远程协议地址

    无欲速,无见小利。欲速,则不达;见小利,则大事不成。
  • 相关阅读:
    git如何忽略文件或者文件夹
    jsonp跨域请求发布出去
    PHP
    curl保存图片
    curl 请求
    输入框纯数字
    PHP允许AJAX跨域请求的两种方法
    IOS开发笔记 IOS如何访问通讯录
    Android 蓝牙开发(整理大全)
    新的移动服务示例
  • 原文地址:https://www.cnblogs.com/ch122633/p/8336557.html
Copyright © 2020-2023  润新知