套接字是通讯端点的抽象
创建一个套接字
#include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); 返回值:成功文件(套接字)描述符,失败-1
domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。 协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。 type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的类型有哪些?)。 protocal:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等 它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
套接字通信是双向的。可以禁止一个套接字的I/O
#include <sys/socket.h> int shutdown(int sockfd, int how); 返回值:成功0,出错-1 sockfd:套接字的描述符 how:三种SHUT_RD(0)关闭sockfd上的读功能 SHUT_WR(1)关闭sockfd上的写功能 SHUT_RDWR(2)关闭sockfd的读写功能
用来在处理器字节序和网络字节序之间实施转换的函数
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
返回值:以网络字节序表示的32位整数
uint16_t htons(uint16_t hostshort);
返回值:以网络字节序表示的16位整数
uint32_t ntohl(uint32_t netlong);
返回值:以主机字节序表示的32位整数
uint16_t ntohs(uint16_t netshort);
返回值:以主机字节序表示的16位整数
h表示主机字节序,n表示网络字节序,l表示长整型,s表示短整型
打印出能被人理解而不是计算机所理解的地址格式。同时支持IPv4和IPv6地址
#include <arpa/inet.h> const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); 返回值:成功地址字符串指针,出错NULL af:地址簇,仅支持AF_INET和AF_INET6 src:来源地址结构指针 dst:接收转换后的字符串 size:保存文本字符串的缓冲区大小 int inet_pton(int af, const char *src, void *dst); 返回值:成功1,格式无效0,出错-1 af:地址簇,仅支持AF_INET和AF_INET6 src:转换的地址字符串 dst:转换后的地址结构指针
这个很常用,所有使用socket都需要用这两个函数转换,p应该是protocol,n应该是net吧。
例子
1 #include <stdio.h> 2 #include <string.h> 3 #include <sys/types.h> 4 #include <sys/ioctl.h> 5 #include <stdlib.h> 6 #include <netdb.h> 7 #include <arpa/inet.h> 8 #include <netinet/in.h> 9 #include <string.h> 10 11 int main(int argc, char *argv[]) 12 { 13 char dst[100]; 14 int sockfd = socket(AF_INET, SOCK_STREAM, 0); 15 16 struct sockaddr_in serv; 17 memset(&serv, 0 ,sizeof(struct sockaddr_in)); 18 19 serv.sin_family = AF_INET; 20 serv.sin_port = htons(5555); 21 22 if((inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr)) == 0) 23 printf("inet_pton error\n"); 24 if((inet_ntop(AF_INET, &serv.sin_addr.s_addr, dst, sizeof(dst))) == NULL) 25 printf("inet_ntop error\n"); 26 printf("dst=%s,sizeof(dst)=%d\n", dst, sizeof(dst)); 27 28 bind(sockfd, (struct sockaddr *)&serv, sizeof(serv)); 29 listen(sockfd, 15); 30 return 0; 31 }