Linux的网络编程

对于多字节数据在内存中有两种存储方式:

Little-endian:低字节在前,高字节在后;

Big-endian:高字节在前,低字节在后

网络协议在处理多字节整数时,采用的是高端字节序,在编程时一定要考虑主机字节顺序与网络字节顺序的相互转换。

1      socket定义

socket是一种文件描述符。常用的socket类型有两种:流式socket(SOCK_STREAM)和数据报式socket(SOCK_DGRAM)。流式是一种面向连接的socket,针对于面向连接的TCP服务应用;数据报式socket是一种无连接的socket,对应于无连接的UDP服务应用。

1.1     socket地址信息

struct sockaddr类型是用来保存socket信息的:

structsockaddr

{

unsigned short sa_family;      /* 地址协议族,一般为AF_INET*/

char sa_data[14];                    /* 14字节的协议地址,包含该socket的IP地址和端口号 */

};

另外还有一种结构类型sockaddr_in:

structsockaddr_in

{

short int sin_family;                     /* 地址族 */

unsigned short int sin_port;        /* 网络字节顺序的端口号*/

struct in_addr sin_addr;              /* IP地址 */

unsigned char sin_zero[8];          /* 填充0 以保持与结构sockaddr同样大小 */

};

sockaddr_in结构使用更为方便,sockaddr_in.sin_zero应该用bzero( )或memset( )将其置为0。sockaddr_in的指针和sockaddr的指针可以通用。

structin_addr

{

unsigned long s_addr;            /* 网络字节顺序的IP地址*/

};

可以将s_addr指定为htonl( INADDR_ANY ),表示的是由系统自己指定IP地址。

在选择端口sin_port时,必须特别小心:

1.0~1023由IANA控制,是为固定服务保留的;

2.1024~49151是IANA列出来的、已注册的端口,供普通用户的普通用户进程或程序使用;

3.49152~65535是动态或私用端口,IANA这些端口上没有注册服务,可自由使用。

1.2     地址格式转换函数

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet>

intinet_aton( const char *cp, struct in_addr *inp )     // 将点式IP转换成网络字节顺序的IP

char* inet_ntoa( struct in_addr in )                              // 将网络字节顺序的IP转换成点式IP

1.3     网络字节顺序转换函数

#include<netinet/in.h>

主机字节顺序---->网络字节顺序:

uint16_t htons(uint16_t hostshort);

uint32_t htonl(uint32_t hostlong);

网络字节顺序---->主机字节顺序:

uint16_t ntohs(uint16_t netshort);

uint32_t ntohl(uint32_t netlong);

1.4     名字解析

structhostent

{

char *   h_name;             //主机名

char ** h_aliases;            //主机别名数组

int          h_addrtype;       //主机地址类型

int          h_length;            //主机地址长度(字节)

char ** h_addr_list;        //主机地址数组,其中的地址是网络字节顺序。

}

 

#include<netdb.h>

structhostent *gethostbyname( const char *name )

参数name可以是主机名,也可以是点式IP地址。

 

#include<sys/socket>

structhostent *gethostbyaddr( const char *addr, int len, int type )

参数addr是指向主机地址的指针,该主机地址按照网络字节顺序。

参数len指定参数addr的字节长度。

参数type为AF_INET。

2      socket的使用

2.1     socket的创建

structprotoent

{

char *   p_name;      //协议名

char ** p_aliases;     //协议别名数组

int          p_proto;      //协议号

}

#include<netdb.h>

structprotoent *getprotoent( void )

 

#include<sys/types.h>

#include<sys/socket.h>

intsocket( int domain, int type, int protocol )

参数domain可以是PF_INET,表示IPv4地址家族;PF_INET6,表示IPv6地址家族。

参数type可以取SOCK_STREAM、SOCK_DGRAM或SOCK_RAW。

参数protocol可以是getprotoent()取回的任何一个协议号,一般取0表示IP。

2.2     面向连接的socket

2.2.1   服务器端函数

2.2.1.1      bind( )

#include<sys/types.h>

#include<sys/socket.h>

intbind( int sockfd,struct sockaddr *my_addr,intaddrlen )

2.2.1.2      listen( )

#include<sys/types.h>

#include<sys/socket.h>

intlisten( int sockfd,int backlog )

backlog指定在请求队列中允许的最大请求数,连接请求将在队列中等待accept( )它们。

2.2.1.3      accept( )

#include<sys/types.h>

#include<sys/socket.h>

intaccept(int sockfd,void *addr,int*addrlen)

addr通常是结构sockaddr_in的指针,用来存放发出连接请求的主机的信息。

addrten作为输入通常指定为sizeof(

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值