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

网络编程函数

2013-10-27 13:28 197 查看
一、网络字节序 
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用bigendian排序方式。主机字节序就是我们平常说的大端和小端模式:不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序这个叫做主机序。
  由于每一台机器内部对变量的字节存储顺序不同,而网络传输的数据是一定要统一顺序的。所以对内部字节表示顺序与网络字节顺序不同的机器,一定要对数据进行转换,从程序的可移植性要求来讲,就算本机的内部字节表示顺序与网络字节顺序相同,也应该在传输数据以前先调用数据转换函数,以便程序移植到其它机器上后能正确执行。真正转换还是不转换是由系统函数自己来决定的。所以在传输多字节整形数时,需要将其转换为网络字节序。有关的转换函数
uint16_thtons(uint16_thostshort);
主机字节顺序转换成网络字节顺序,对无符号短型进行操作
uint32_thtonl(uint32_thostlong);
主机字节顺序转换成网络字节顺序,对无符号长型进行操作
以上函数的参数就是本地主机序的整数。返回值是:TCP/IP网络字节序
uint16_tntohs(uint16_tnetshort);
网络字节顺序转换成主机字节顺序,对无符号短型进行操作
uint32_tntohl(uint32_tnetlong);
网络字节顺序转换成主机字节顺序,对无符号长型进行操作
注:以上函数原型定义在netinet/in.h里
intinet_aton(constchar*cp,structin_addr*inp);
        功能:将一个字符串IP地址转换为一个32位的网络序列IP地址。
        参数:
            cp:点分十进制的字符串IP地址
            inp:存放转换好的32位网络字节序
        返回值:成功返回非0值,如果地址不正确会返回0.并不设置errno
char*inet_ntoa(structin_addrin);
        功能:将32位的网络字节序转换为字符串IP地址
        参数:
            in:32位网络字节序IP地址。
    返回值:成功返回指向字符串的指针。错误,返回NULL。
注:inet_aton和inet_ntoa仅适用于IPV4协议
intinet_pton(intaf,constchar*src,void*dst);
功能:将一个字符串IP地址转换为一个网络序列IP地址
参数:
            af:AF_INET:需要转换的得IPV4地址,函数将该地址转换为in_addr的结构体
                AF_INET6:需要转换的是IPV6地址,函数将该地址转换为in6_addr的结构体
           src:字符串IP地址
         dst:存放转换好的IP地址
返回值:成功返回1,当src为无效值时,返回-1,当af为无效值时,返回0;
constchar*inet_ntop(intaf,constvoid*src,char*dst,socklen_tsize);
    功能:将网络字节序地址转换为字符串IP地址
参数:
      af:AF_INET:需要转换的得IPV4地址,函数将该地址转换为in_addr的结构体
            AF_INET6:需要转换的是IPV6地址,函数将该地址转换为in6_addr的结构体
    src:网络字节序IP地址
 dst:存放转换好的字符串IP地址
size:是所指向缓存区dst的大小,避免溢出,如果缓存区太小无法存储地址的值,则返回一个空指针
返回值:成功返回一个指向dst的非空指针,失败返回一个NULL
二、其他函数:
网络编程的一些结构体:
   structsockaddr{
       unsignedshortsa_family;   是2字节的地址家族,一般都是“AF_xxx”的形式。
      charsa_data[14]; sa_data:是14字节的协议地址。  };
由于上面的通用结构体易用性不是很好,所以一般使用下面的结构体。
structsockaddr_in{  shortintsin_family;   指代协议族  unsignedshortintsin_port;   存储端口号(使用网络字节顺序)  structin_addrsin_addr;    存储IP地址,使用in_addr这个数据结构  unsignedcharsin_zero[8];  是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。  };
typedefstructin_addr{ unsignedlongs_addr;    用一个长整型来表示IP地址。} 
intsocket(intdomain,inttype,intprotocol);
        功能:创建一个套接字
     参数:
                domain:AF_INET: IPV4协议
                      AF_INET6:IPV6协议
                       AF_LOCAL:Unix域协议
                       AF_ROUTE:路由套接口
                       AF_KEY:密钥套接口
            type:SOCK_STREAM:字节流套接口 ,面向连接的,可靠地字节流。TCP协议
                        SOCK_DGRAM:数据报套接口,无连接的不可靠报文传递。UDP协议
                        SOCK_RAW:原始套接口,IP协议的数据报接口,需要超级用户权限。绕过TCP,UDP传输协议。
          protocol:一般为0,当使用原始套接字时除外。
    返回值:成功返回一个新的套接字描述符,失败返回-1.
intbind(intsockfd,conststructsockaddr*addr,socklen_taddrlen);
        功能:将一本地地址与一套接口捆绑        参数:                sockfd表示已经建立的socket编号(描述符)
 addr:是一个指向sockaddr结构体类型的指针;如果只为INADDR_ANY,套接字可以被绑定到系统的任一可用的网络地址,这意味着可以收到这个系统所安装的所有网卡的数据包。
                   addrlen:表示structsockaddr结构的长度,可以用sizeof函数获得。
        返回值:成功返回0,失败返回-1;
注:端口号一般不要小于5000,当端口设置为0时, 随机选择一个没有使用的端口。当使用INADDR_ANY时,这时bind其实并没有绑定。 
intgetsockname(intsockfd,structsockaddr*addr,socklen_t*addrlen);
        功能:用于获取一个已绑定到套接字的地址(IP地址和端口号等)
    参数:
       sockfd:套接字描述符
        addr:将返回的地址放到addr中。
addrlen:该数在调用函数以前被设置为structsockaddr的长度,当函数返回时,该数会被设为structsockaddr的大小,如果两者不匹配,则将其截短不报错。
返回值:成功返回0,出错返回-1
注:如果当前套接字没有绑定任何地址,则其结果没有定义。 若一个套接口与INADDR_ANY捆绑,也就是说该套接口可以用任意主机的地址,此时除非调用connect()或accept()来连接,否则getsockname()将不会返回主机IP地址的任何信息
int getpeername(int sockfd, struct sockaddr *addr,socklen_t*addrlen);
        功能:若套接字已经和对方连接,获得对方的地址(IP地址和端口号等)
        参数:
                sockfd:套接字描述符
                addr:将返回的地址放到addr中。
addrlen:该数在调用函数以前被设置为structsockaddr的长度,当函数返回时,该数会被设为structsockaddr的大小,如果两者不匹配,则将其截短不报错。
    返回值:成功返回0,出错返回-1
    注:该套接字必须已与一个地址连接,否则返回不确定。
intconnect(intsockfd,conststructsockaddr*addr,socklen_taddrlen);
        功能:在使用面向连接的网络服务以前,需在客户端和服务器端建立一个连接,可以使用connect来建立连接        参数:              sockfd:套接字文件描述符              addr:要连接的目的地址              addrlen:structsockaddr的长度    返回值:成功返回0,失败返回-1
注:
如果sockfd并没有绑定到一个地址,connect会给调用者绑定一个默认地址。如果connect失败,则套接口不可再用,必须关闭,不能在对此套接口调用connect。必须关闭后,重新调用socket创建一个套接口 connect还可以用于无连接的网络服务,如果在SOCK_DGRAM套接字上调用connect,所有发送报文的目标地址设为connect调用中所指定的地址,这样,每次在传送报文时,就不需要再提供地址。另外,仅能接受来自指定地址的报文。
intlisten(intsockfd,intbacklog);
        功能:设置可以监听最大连接请求,包括已连接的和未连接的
        参数:
                  sockfd:套接字描述符
                  backlog:最大连接请求数
        返回值:成功返回0,失败返回-1
注:当socket创建一个套接口时,它被假设为一个主动接口,也就是说,他是一个将调用connect发起连接的客户套接口,函数listen将未连接的套接口转换成被动套接口,只是内核应接受向此套接口的连接请求。调用listen导致套接口从CLOSED状态转换到LISTEN状态。一旦调用了listen,套接字就能接受连接请求。
不要将backlog定义为0,一位不同实现对此有不同解释,有些实现容许有一个连接排队,有的则不容许有连接排队。
intaccept(intsockfd,structsockaddr*addr,socklen_t*addrlen);
        功能:等待接受连接请求。
        参数:
              sockfd:套接字描述符
              addr:用来存放返回的客户端地址
addrlen:在此函数调用前,将addrlen设置为addr所指向的套接字地址结构的长度。当此函数返回后,此数便被设置成由内核定义的此套接字地址结构的准确长度。
返回值:成功返回一个新的套接字描述符,该描述符连接到调用connect的客户端,这个新的描述符合原始套接字(sockfd)具有相同的套接字类型和地址族。以后对连接的客户端操作时,便使用这个新的描述符。失败返回-1.
注:如果当前没有未完成的连接请求,则此函数睡眠阻塞。如果sockfd处于非阻塞模式下,则会返回-1。因为一般情况下服务器创建的sockfd还要用于接收其它客户端的连接请求。所以accept要返回一个新的描述符。而sockfd继续等待别的连接请求。而connect用于客户端,一般只与一个服务器连接,所以不返回一个新的描述符
三、数据传送函数
ssize_tsend(intsockfd,constvoid*buf,size_tlen,intflags);
            功能:发送数据
            参数:
          sockfd:套接字描述符
          buf:待发送数据的缓冲区。
          len:要发送的数据长度
          flags:
                        MSG_OOB发送带外数据。
                        MSG_DONTROUTE勿将数据路由出本地网络
MSG_DONTWAIT允许非阻塞操作
        返回值:成功则返回实际传送出去的字符数,失败返回-1
        注:使用send时,套接字必须是已连接的,因为send不知道要将数据发送何处。当套接字输出队列没有足够的空间来发送消息时,send会阻塞,同样适用于下列两个函数sendto和sendmsg。但当套接字在非阻塞模式下士时,情况会改变,在这种情况下,这些函数不会阻塞而是失败。
ssize_tsendto(int sockfd,constvoid*buf,size_tlen,int flags,conststructsockaddr*dest_addr,socklen_t addrlen);
            功能:发送数据
            参数:
                 sockfd:套接字描述符
        buf:待发送数据的缓冲区。
        len:要发送的数据长度
        flags:
MSG_OOB发送带外数据。
MSG_DONTROUTE勿将数据路由出本地网络
MSG_DONTWAIT允许非阻塞操作
        dest_addr:将要发送的目标地址
     addrlen:structsockaddr的长度
    返回值:成功则返回实际传送出去的字符数,失败返回-1
ssize_tsendmsg(intsockfd,conststructmsghdr*msg,intflags);
            功能:发送数据
        参数:
        sockfd:套接字描述符
        msg:
             structmsghdr{
                                          void      *msg_name;                                          socklen_t  msg_namelen;                      structiovec*msg_iov;                                          size_t    msg_iovlen;                                          void      *msg_control;                                          size_t    msg_controllen;                                          int      msg_flags;                                };
        flags:
MSG_OOB发送带外数据。
MSG_DONTROUTE勿将数据路由出本地网络
MSG_DONTWAIT允许非阻塞操作
    返回值:成功则返回实际传送出去的字符数,失败返回-1
    注:
对于以上三个函数,当套接字输出队列没有足够的空间来发送消息时,则会一直阻塞。但当套接字在非阻塞模式下时,情况会改变,在这种情况下,这些函数不会阻塞而是失败。如果调用shutdow关闭了读端或者服务器端进程关闭socket以后,则当前进程收到一个SIGPIPE信号,终止进程
ssize_trecv(intsockfd,void*buf,size_tlen,intflags);
    功能:接收数据
   参数:
                 sockfd:套接字描述符
                buf:接收数据的缓冲区。
                 len:要接收的数据长度
                 flags:
             MSG_OOB接收带外数据。
MSG_DONTWAIT允许非阻塞操作
MSG_TRUNC一般数据被截断
MSG_TRUNC控制数据被截断
MSG_TRUNC控制数据被截断
MSG_EOR接收到记录结束符
            返回值:成功返回读到的字节数,失败返回-1.
注:如果调用shutdow关闭了发送端,则当所有数据接收完毕后,返回0;当客户端进程关闭时,ssize_trecvfrom(intsockfd,void*buf,size_tlen,intflags,structsockaddr*src_addr,socklen_t*addrlen);
    功能:接收数据
  参数:
       sockfd:套接字描述符
       buf:接收数据的缓冲区。
         len:要接收的数据长度
flags:
    MSG_OOB接收带外数据。MSG_DONTWAIT允许非阻塞操作MSG_TRUNC一般数据被截断MSG_TRUNC控制数据被截断MSG_EOR接收到记录结束符
src_addr:将返回的发送者地址存放在src_addr中。
addrlen:在此函数调用前,将addrlen设置为addr所指向的套接字地址结构的长度。当此函数返回后,此数便被设置成由内核定义的此套接字地址结构的准确长度。
返回值:成功返回读到的字节数,失败返回-1.
ssize_trecvmsg(intsockfd,structmsghdr*msg,intflags);
        功能:接收数据
    参数:
       sockfd:套接字描述符
      msg:
                          structmsghdr{
                                          void      *msg_name;                                          socklen_t  msg_namelen;                      structiovec*msg_iov;                                          size_t    msg_iovlen;                                          void      *msg_control;                                          size_t    msg_controllen;                                          int      msg_flags;                                };
            flags:
                       MSG_OOB接收带外数据。
                    MSG_DONTWAIT允许非阻塞操作
MSG_TRUNC一般数据被截断
MSG_TRUNC控制数据被截断
MSG_EOR接收到记录结束符
        返回值:成功返回读到的字节数,失败返回-1.
注:
当服务器的sockfd和地址绑定以后,以上三个recv函数,可以接受任何向此地址发送数据的连接,并没有指定要接受的地址。以上三个函数当为阻塞模式下时,如果没有数据可读,则阻塞。如果调用shutdow关闭了发送端或者客户端进程关闭socket以后,则当所有数据接收完毕后,返回0;
四、套接字选项:
intgetsockopt(intsockfd,intlevel,intoptname,void*optval,socklen_t*optlen);
        功能:获得套接字的选项(属性)
        参数:
                 socket:套接字描述符   
                    level:选项所在的协议层。见下表1.1
                    optname:选项名称,见下表1.1
optval:将获得的相应选项的开关状态存放在optval中,如果为0,表示此选项关闭,非0,表示此选项被启用。
            optval必须指向每个选项的数据类型。
    optlen:optval的大小
    返回值:成功返回0,出错返回-1
intsetsockopt(intsockfd,intlevel,intoptname,constvoid*optval,socklen_toptlen);            功能:设置一个套接字的选项(属性)
参数:
  socket:套接字描述符
    level:选项所在的协议层。见下表1.1
    optname:选项名称,见下表1.1
    optval:没有特殊说明时,默认为整形设置相应选项的开关状态,如果为0,表示要将此选项关闭,非0,表示要将此选项启用。如果为特殊说明结构,则需要按照结构设置。
            optval必须指向每个选项的数据类型。
    optlen:optval的大小
返回值:成功返回0,失败返回-1.
                                              表1.1

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