UNP第3章 套接字编程简介

时间:2022-10-31 11:01:09

1.套接字地址结构

IPv4套接字地址结构
struct in_addr{
  in_addr_t s_addr;//32位的IPv4网络字节序
}

struct sockaddr_in{
  uint8_t sin_len;//带符号8位整数地址结构长度
  sa_family_t sin_family;//协议族,IPv4为AF_INET
  in_port_t sin_port;//端口号
  struct in_addr sin_addr;//32位IPv4网络字节序地址
  char sin_zero[8];//填充对齐位,未使用
};


通用套接字地址结构
struct sockaddr{
  uint8_t sa_len;
  sa_family_t sa_family;
  char sa_data[14];
}
ps:这些套接字的唯一用处就是对指向特定于协议的套接字地址结构的指针执行类型强制转换,例如:
struct sockaddr_in serv;
bind(sockfd,(struct sockaddr*)&serv,sizeof(serv));
IPv6套接字地址结构
struct in6_addr{
  uint8_t s6_addr[16];//128位IPv6网络字节序地址
};

#define SIN6_LEN
struct sockaddr_in6{
  uint8_t sin6_len; //这个结构的长度
  sa_family_t sin6_family;//协议族 AF_INET6
  in_port_t sin6_port;//端口号,网络字节序

  uint32_t sin6_flowinfo;//流信息,未定义
  struct in6_addr sin6_addr;//IPv6地址

  uint32_t sin6_scope_id;
};

 

2.字节排序函数
大端字节序:高字节在低地址
小端字节序:低字节在高地址
网络字节序:网络字节序采用大端字节序
主机字节序:本地主机使用的字节序,可能为大端或小端

主机字节序与网络字节序转换函数
#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);//主机to网络 short
uint32_t htonl(uint32_t host32bitvalue);//主机to网络 long
uint16_t ntohs(uint16_t net16bitvalue);//网络to主机 short
uint32_t ntohl(uint32_t net32bitvalue);//网络to主机 long

 

3.字节操纵函数
#include <strings.h>
void bzero(void *dest,size_t nbytes); //将目标字符串制定数目的字节置0
void bcopy(const void *src,void *dest,size_t nbytes);//拷贝指定字节
int bcmp(const void*ptrl,const void *ptr2,size_t nbytes);//若相等返回0

ANSI C函数:
#include<string.h>
void *memset(void *dest,const void *src,size_t len);
void *memcpy(void *dest,const void *src,size_t nbytes);
int memcpy(const void *ptrl,const void *ptr2,size_t nbytes);

 

4.点分十地址与32位网络字节序地址的转换
#include <arpa/inet.h>
//将点分十地址转换为32位网络字节序,用struct in_addr存储
int inet_aton(const char *strptr,struct in_addr *addrptr);
in_addr_t inet_addr(const char*strptr);//返回32位网络字节序地址
char *inet_ntoa(struct in_addr inaddr);//返回点分十地址


5.适合IPv4和IPv6的转换函数
#include <inet.h>
int inet_pton(int family,const char *strptr,void *addrptr);
const char *inet_ntop(int family,const void*addrptr,char *strptr,size_t len);

 

6.readn、writen和readline函数

#include "unp.h"
ssize_t readn(
int fields,void *buff,size_t nbytes);
ssize_t written(
int fields,const void *buf,size_t nbytes);
ssize_t readline(
int fields,void *buff,size_t maxlen);
//三个函数分别封装了read write

//readn
#include "unp.h"
ssize_t readn(
int fd,void *vptr,size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;

ptr
= vptr;
nleft
= n;
while(nnleft > 0)
{
if((nread = read(fd,ptr,nleft)) < 0 )
{
if(errno == EINTR)
{
nread
= 0;
}
else
{
return -1;
}
}
else if(nread == 0)
{
break;
}
nleft
-= nread;
ptr
+= nread;
}
return (n-nleft);
}

//written
#include "unp.h"
ssize_t written(
int fd,void *vptr,size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr
= vptr;
nleft
= n;
while(nlfet > 0)
{
if((nwritten = writen(fd,ptr,nleft)) <= 0)
{
if(nwritten < 0 && errno ==EINTR)
{
nwritten
=0;
}
else
{
return -1;
}
}

nleft
-= nwritten;
ptr
+= nwritten;
}
return n;
}