套接字使用时候的一些注意

来源:互联网 发布:windows开启samba 编辑:程序博客网 时间:2024/04/27 09:36
创建套接字
int socket(int domain, int type, int protocol);
返回sockfd(套接字地址描述符)
domain为地址族,一般为:
PF_INET  internet协议(网络地址协议)
PF_UNIX  unix internet协议(本地地址协议)
PF_NS  Xerox NS协议
PF_IMPLINK interface Message协议
type 套接字类型
SOCK_STREAM  流式套接字
SOCK_DGRAM  数据报套接字
SOCK_RAW   原始套接字
protocol 参数通常置为0 (原始套接字使用时需要注意下)
bind(int sockfd, struct sockaddr*addr, int addrlen);
绑定本地地址与端口
主要说下struct sockadd这个结构体。
这是个通用地址结构
struct sockaddr
{
        u_short sa_family;//地址族,PF_XXX
        char sa_data[14];//14字节协议地址
};
其实在实际使用中并不直接用通用地址来传递或绑定IP与端口信息。
而是使用
Internet协议地址结构来保存
struct sockaddr_in
{
         u_short sin_family;//地址族,PF_INET,2 bytes
         u_short sin_port;//端口,2 bytes
         struct in_addr sin_addr;//IPV4地址4bytes
         char sin_zero[8];          //8 bytes unused ,作为填充,因为要将此类型强制转化为struct sockaddr需要16个字节
};
其中
struct in_addr 
{
          in_addr_t s_addr;            //u32 network address
};
然后将此类型强制转化为struct sockaddr *类型
而这里又要涉及到IP地址如何由点分十进制转化为u32网络地址
unsigned long inet_addr(char *address);
struct in_addr addr;
addr.s_addr = inet_addr("192.168.1.100");

将U32网络地址转化为char *
char * inet_ntoa(struct in_addr address);

对于端口的转化又要牵扯到字节序问题
因为不同CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):
小端序.低序字节存储在低地址。将低字节存储在起始地址。intel,AMD
大端序:高序字节存储在低地址。将高字节存储在起始地址。ARM,Motorola
而网络中传输的数据必须按网络字节序,即大端字节序(NBO)
故在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当应用进程从socket取出整数后,要转化成小端字节序。

由主机字节序转化为网络字节序的函数:
u_long htonl(u_long hostlong);
u_short htons(u_short short);
由网络字节序到主机字节序
u_long ntohl(u_long hostlong);
u_short ntohs(u_short short);
将字符串转化为整形又要用到atoi函数

由此有人或许要问为什么IP地址不需要转化字节序:这是因为inet_addr函数本身就已经对字节序进行了转化,而inet_ntoa也在转化为字符串时将网络字节序转化为本机字节序。


关于_u32和ip地址的转换问题:

static unsigned char *ip_address = "\xC0\xA8\x00\x01";
if(sock_buff->nh.iph->saddr == *(unsigned int*)ip_address){ return NF_DROP; }

sock_buff->nh.iph->saddr 
是_u32类型的。将十进制点ip地址转换时,只需将其以unsigned char*存储。然后用(unsigned int * )强制转换。


原创粉丝点击