zoukankan      html  css  js  c++  java
  • 第四章 基本TCP套接字编程

    1. socket函数

    #include <sys/socket.h>
    //成功返回非负,失败返回-1
    int socket(int family, int type, int protocol);

    参数说明:

    family指明协议族取值如下图

    type指明套接字类型

    protocol指明协议

    当Protocol值为0时系统根据family和type的组合指定默认值

    关于AF_XXX和PF_XXX

         AF_前缀表示地址族,PF_前缀表示协议族。历史想法:单个协议族可以支持多个地址族,PF_值用于创建套接字,AF_值用于套接字地址结构。实际上支持多个地址族的协议族从来没实现过,现<sys/socket.h>中给出的PF_值大多和AF_值相等。

    2. connect函数

    #include <sys/socket.h>
    int connect(int sockfd, const struct sockaddr *servaddr, socklet_t addrlen);

    如果是TCP套接字,此函数触发TCP三次握手连接,在连接成功或出差时才返回,错误可能有以下情况:

    1)TCP客户没有收到SYN分节响应;

    2)SYN的响应是RST,这是一种硬错误,会马上返回ECONNREFUSED错误;

    3)发出的SYN在中间某个路由引发"destination unreachable"。

    说明:connect函数导致当前套接字从COLSED状态转移到SYN_SEND状态,若成功则转移到ESTABLISHED状态,若失败则该套接字不再可用,必须关闭。所以每次connect失败后都必须close当前套接字,并重新调用socket创建。

    3. bind函数 

    #include <sys/socket.h>
    int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);

    参数说明:对于TCP调用bind函数可以指定一个端口或指定一个IP地址,也可以两者都不指定或两者都指定。

    1)服务器一般都会指定端口,例外是远程过程调用(RCP);

    2)进程可以把一个特定的IP捆绑到它的套接字,但是次IP必须是其所在主机的网络接口之一。

    指定IP或端口预期值如下图:

    对于IPv4通配地址通常由INADDR_ANY指定。

    bind常返回的一个错误是EADDRINUSE(Address already in use)

    4. listen函数

    #include <sys/socket.h>
    int listen(int sockfd, int backlog);

     listen由服务器调用,做以下两件事:

    1)socket函数创建套接字时,它被认为是主动套接字,listen把一个未连接的主动套接字转换成一个被动套接字。listen导致套接字从CLOSE状态转换到LISTEN状态;

    2)为内核规定相应套接字排队的最大连接数(可以看成包含已经连接完成连接ESTABLISHED状态的和未完成连接的)。

    backlog参数值的解析:

    1)不要把backlog参数指定为0,因为不同的实现处理方式不同;

    2)backlog并不是未完成连接队列+已完成连接队列的和。

    3)backlog值与排队连接的最大数目不同系统不同。这个值最好设置成可配置的。

    6. accept函数 

    #include <sys/socket.h>
    int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

    说明:

    • cliaddr与addrlen返回已连接的客户进程的协议地址,addrlen是值-结构参数
    • 对客户的身份不感兴趣可以把chiaddr与addrlen都设置成NULL
    • 区分监听套接字和已连接套接字。监听套接字由socket创建在服务器的生命周期内一直存在,已连接套接字是连接成功时accept返回的值,当客户端断开连接时已连接套接字也被关闭。

    7. fork和exec函数

    8. 并发服务器:父子进程共享套接字描述符。每个套接字都有一个引用计数。

    9.close函数

    #include <unistd.h>
    int close(int sockfd);

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

    说明:

    • getsockname:在一个没有调用bind的TCP客户上,connect成功返回后,其返回由内核赋予该连接的本地IP和端口号;以端口号0调用bind后,getsockname用于返回由内核赋予的本地端口号;getsockname可获得某个套接字的地址族;以通配IP调用bind的服务器上,和客户端连上后getsockname可获得由内核赋予的本地ip地址
    • 服务器是由调用过accept某个进程通过调用exec执行程序时,它能获取客户身份的唯一途径是经过getpeername。(fock->exec)

    注:两个函数最后一个参数都是值-结果参数。

    返回套接字地址族例子:

    int sockfd_tofamily(int sockfd)
    {
        struct sockaddr_storage ss;
        socklen_t len;
        len = sizeof(ss);
        if(getsockname(sockfd, (SA*) &ss, &len) < 0)
        {
            return -1;
        }
        return ss.ss_family;
    }
  • 相关阅读:
    thinkphp传递参数
    $this->display输出模板
    ConterReplaceBehavior.class.php模板内容替换,如__PUBLIC__
    Index/Common目录下文件
    thikphp创建共享数据config.php
    thinkphp连接数据库
    thinkphp笔记
    thinkphp安装 版本 3.1.3
    DIV CSS 网页兼容全搞定 (IE6 IE7 IE8 IE9 火狐 谷歌)
    js倒计时
  • 原文地址:https://www.cnblogs.com/4tian/p/2622826.html
Copyright © 2011-2022 走看看