首页未分类 › Linux C socket 常用函数和结构体

Linux C socket 常用函数和结构体

Linux C socket 常用函数和结构体

struct sockaddr是通用的套接字地址,一般用于向函数传参

struct sockaddr { 

       u_short sa_family;          /*address family */

        char   sa_data[14];      /* up to 14 bytes of direct address */

};

 

结构体sockaddr_un和sockaddr_in用于保存套接字的信息

struct sockaddr_un{      //一般用于进程间通信

   sa_family_t sun_family;//AF_UNIX

   char sun_path[];   //pathname

}

 

struct sockaddr_in{           //一般用于网络编程

   unsigned short int sin_family;//AF_INET

   uint16_t sinport;  //端口号

   struct in_addr sin_addr;   //IP地址

   unsigned char sin_zero[8];  //未使用字段 保证sockaddr_in和sockaddr大小一致

}

 

struct in_addr{

 uint32_t s_addr;   //长整形数  比如s_addr=16885952

}

主机信息结构体

struct hostent{

  char * h_name;             //正式的主机名称

  char ** h_aliases;         //主机的别名 数组多个别名

  int h_addrtype;            //主机名的类型

  int h_length;              //地址的长度

  char **h_addr_list;        //主机的IP地址 数组

}

典型h_addr_list字段的处理:printf(”%s\n”,inet_ntoa(*(struct in_addr*)*h_addr_list));

 

服务信息结构体

struct servent{

  char * s_name;    //服务名称

  char **s_aliases;   //服务别名

  int s_port;        //端口号

  char * s_protol;    //”tcp”  “udp”

}

 

用域名取得主机的IP地址

struct hostent * gethostbyname(const char *name);//name:域名

通过哪个主机拥有某个IP地址

struct hostent * gethostbyaddr(const void *addr,size_t len,int type);

 

如果没有查到相关信息,上边两个函数返回NULL

 

查询标准服务所用的端口

struct servent * getservbyname(const char *name,const char * protocol);//name服务名  protocol 协议名:”tcp” “udp”

查询某个端口所用于的服务

struct servent * getservbyport(intport,const char * proto);//port端口号 proto协议名

 

IP地址的转化

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

点分十进制向长整形转化

long inet_addr(char * cp);

长整形向点分十进制转化

char * inet_ntoa(struct in_addr in);

 

 

创建套接字

#include <sys/types.h>

#include <sys/socket.h>

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

domain:协议族 常用:AF_UNIX AF_INET

type: 通讯特性 SOCK_DGRAM,一般用在网络UDP SOCK_STREAM,一般用在网络TCP

protocol:一般不用 设为0

返回值:返回一个描述符

 

命名套接字

#include <sys/socket.h>

int bind(int socket,const struct sockaddr *address,size_t address_len);

bind系统调用把参数address中的地址分配符与描述符socket关联的未命名套接字,地址长度由address_len 决

 

创建套接字队列

服务器程序必须创建一个队列来保存未处理的请求

#include <sys/socket.h>

int listen(int socket,int backlog);

在套接字队列中,等待处理的进入连接的个数最多不能超过backlog个数,否则将被拒接连接 backlog一般为5

成功时返回0 失败时返回-1

 

接受连接

一旦服务器创建并命名了套接字之后,他就可以通过用accept来等待客户建立对该套接字的连接

int accept(int socket,struct sockaddr * address,size_t * address_len);

accept函数创建一个套接字来和该客户进行通信连接客户的地址将被放入address指向的结构体,如果不关心连接

客户的地址,可置位NULL,address_len指定客户结构的长度,如果客户地址超过这个长度,他将被截断

 

请求连接

客户程序通过在一个未命名套接字和服务器监听套接字之间建立连接

int connect(int socket,const structsockaddr*address,size_t address_len);

参数socket指定的套接字将连接到address指定的服务器套接字,address_len指定长度

 

关闭套接字

通过close来关闭套接字,应该总是在连接的两端同时关闭套接字

 

主机字节序和网络字节序

#include <netinet/in.h>

unsigned long int htonl(unsigned long inthostlong);

unsigned short int htons(unsigned short inthostshort);

unsigned long int ntohl(unsigned long intnetlong);

unsigned short int ntohs(unsigned short intnetshort);

这些函数将16位和32位整数在主机字节序和网络字节序之间进行转换,如果计算机本身的主机字节序与网络字节

序相同,这些函数就是空操作

 

例如 sever_address.sin_addr.s_addr=htonl(INADDR_ANY);

    sever_address.sinport=htons(9734);

函数inet_addr();返回的就是网络字节序,无需转化

发表评论