linux socket

sockaddr和sockaddr_in的区别

sockaddr是在头文件 /usr/include/bits/socket.h 中定义的,如下:

/* Structure describing a generic socket address.  */                                                  
struct sockaddr                                                                                        
  {                                                                                                    
    __SOCKADDR_COMMON (sa_); //field: sa_family                        
    char sa_data[14];  /* Address data.  */                                                   
  }; 

而sockaddr_in是在头文件 /usr/include/netinet/in.h 中定义的,如下:

struct sockaddr_in                                                                                     
  {                                                                                                    
    __SOCKADDR_COMMON (sin_);           // field: sin_family                                                             
    in_port_t sin_port;                 /* Port number.  */                                            
    struct in_addr sin_addr;            /* Internet address.  */                                       

    /* Pad to size of `struct sockaddr'.  */                                                           
    unsigned char sin_zero[sizeof (struct sockaddr) -                                                  
                           __SOCKADDR_COMMON_SIZE -                                                    
                           sizeof (in_port_t) -                                                        
                           sizeof (struct in_addr)];                                                   
  };

其中__SOCKADDR_COMMON宏在/usr/include/bits/sockaddr.h中定义,如下:

typedef unsigned short int sa_family_t; 

#define __SOCKADDR_COMMON(sa_prefix) \                                                              
  sa_family_t sa_prefix##family                                                                     

#define __SOCKADDR_COMMON_SIZE  (sizeof (unsigned short int))                                          

#endif 

二者的占用的内存大小是一致的,因此可以互相转化,从bit意义上说,他们并无区别。

sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。一般情况下sockaddr是系统调用的参数,程序员编写的程序中并不直接针对此数据结构操作,而是使用sockaddr_in,调用系统调用的时候需要将sockaddr_in强制转换成sockaddr在传入系统调用。sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。

socket函数

       #include 
       #include 

       int socket(int domain, int type, int protocol);

creates an endpoint for communication and returns a descriptor.

参数

domain: 指定协议簇/协议域。可用的协议簇定义在linux/socket.h中。

   Name                Purpose                          Man page
   PF_UNIX, PF_LOCAL   Local communication              unix(7)
   PF_INET             IPv4 Internet protocols          ip(7)
   PF_INET6            IPv6 Internet protocols
   PF_IPX              IPX - Novell protocols
   PF_NETLINK          Kernel user interface device     netlink(7)
   PF_X25              ITU-T X.25 / ISO-8208 protocol   x25(7)
   PF_AX25             Amateur radio AX.25 protocol
   PF_ATMPVC           Access to raw ATM PVCs
   PF_APPLETALK        Appletalk                        ddp(7)
   PF_PACKET           Low level packet interface       packet(7)

注意domain是PF_XXX,其中PF=protocol familiy是协议簇的意思, 而AF_XXX中AF=address family是地址簇的意思。据说是最开始的时候设计者设想一个AF可以支持多个PF,后来就没有后来了,所以目前PF_XXX和AF_XXX是等效的。
type: 套接口类型,指明通信语义,目前支持如下通信语义

   SOCK_STREAM
          Provides sequenced, reliable, two-way, connection-based byte  streams.   An  out-of-band
          data transmission mechanism may be supported. 

   SOCK_DGRAM
          Supports datagrams (connectionless, unreliable messages of a fixed maximum length).

   SOCK_SEQPACKET
          Provides  a  sequenced,  reliable,  two-way  connection-based data transmission path for
          datagrams of fixed maximum length; a consumer is required to read an entire packet  with
          each read system call.

   SOCK_RAW
          Provides raw network protocol access.

   SOCK_RDM
          Provides a reliable datagram layer that does not guarantee ordering.

   SOCK_PACKET
          Obsolete and should not be used in new programs; see packet(7).

一般TCP使用SOCK_STREAM,UDP使用SOCK_DGRAM。

protocol:
一般设置为0.

Sockets of type SOCK_STREAM are full-duplex byte streams, similar to pipes. They do not preserve record boundaries. A stream socket must be in a connected state before any data may be sent or received on it. A connection to another socket is created with a connect(2) call. Once connected, data may be transferred using read(2) and write(2) calls or some variant of the send(2) and recv(2) calls. When a session has been completed a close(2) may be performed. Out-of-band data may also be transmitted as described in send(2) and received as described in recv(2).

The communications protocols which implement a SOCK_STREAM ensure that data is not lost or duplicated. If a piece of data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, then the connection is considered to be dead. When SO_KEEPALIVE is enabled on the socket the protocol checks in a protocol-specific manner if the other end is still alive. A SIGPIPE signal is raised if a process sends or receives on a broken stream; this causes naive processes, which do not handle the signal, to exit. SOCK_SEQPACKET sockets employ the same system calls as SOCK_STREAM sockets. The only difference is that read(2) calls will return only the amount of data requested, and any remaining in the arriving packet will be discarded. Also all message boundaries in incoming datagrams are preserved.

return value
-1 if error occurs; fd else success

setsockopt

你可能感兴趣的:(操作系统)