API中用到的结构体
#1. struct sockaddrstruct sockaddr {u_char sa_len;u_short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};sockaddr包含两部分内容:
1. 短整型sa_family定义了地址家族类型,这个类型会用于socket()函数
2. 14字节的sa_data数组预留保存本身的地址
注意:
1.原本没有sa_len
2. 根据sa_family的不同类型,sa_data里存放的可能是IP地址也可能是socket端点(socket endpoint)
3. 为了处理这个结构体,另一个结构体常常被用到sockaddr_in(in是internal的意思)
#2. struct sockaddr_in
struct sockaddr_in {u_char sin_len;
u_short sin_family; // Address family
u_short sin_port; // Port number
struct in_addr sin_addr; // Internet or IP address
char sin_zero[8]; // Same size as struct sockaddr
};
1. sin_family和sockaddr中的sa_family一样
2. sin_port是端口号
3. sin_zero是保留段,一般全部置0
4. sin_addr和sin_port必须是符合网络字节流顺便的编码
API中常用的方法
#1. int socket(int domain, int type, int protocol);
1. domain应该设置为AF_INET,和sockaddr_in中一致2. type告诉系统内核是那一种socket,比如SOCK_STREAM or SOCK_DGRAM3. protocal一般是0,或者使用getprotobyname()方法获取4. 这个方法的返回值是一个socket 辨识字(socket descriptor),可用来接下来的系统调用int bind(int sockfd, struct sockaddr *my_addr, int addrlen);#2. int bind(int sockfd, struct sockaddr *my_addr, int addrlen);1. sockfd就是上个方法中放回的辨识字2. addrlen可以用sizeof(struct sockaddr)#3. int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);#4. int listen(int sockfd, int backlog);
1. backlog 确定等待连接队列的长度
2. 应该在使用listen之前调用bind方法,否则系统将会使用一个随机端口
#5. int accept(int sockfd, struct sockaddr *addr, int *addrlen);
#6. ssize_t write(int fd, const void *buf, size_t count);
#7. ssize_t read(int fd, void *buf, size_t count);
#8. int close(int sockfd);