标签:最大 组成 部分 地址解析 链路 images please 流式 自动
sockaddr和sockaddr_in两个结构体用来保存socket的信息,如下所示: struct sockaddr { unsigned short sa_family;/*地址族*/ char sa_data[14];/*14字节的协议地址,包含该socket的IP地址和端口*/ }; struct sockaddr_in { short nt sa_family;/*地址族*/ unsigned short int sin_port;/*端口号*/ struct in_addr sin_addr;/*IP地址*/ unsigned char sin_zero[8];/*填充0以保持与struct sockaddr同样大小*/ };
结构头文件 | #include |
sa_family | AF_INET:IPv4协议 |
AF_INET6:IPv6协议 | |
AF_LOCAL:UNIX域协议 | |
AF_LINK:链路地址协议 | |
AF_KEY:密钥套接字(socket) |
所需头文件 |
#include
|
函数原型 |
uint16_t htons(uint16_t host16bit)
uint32_t htonl(uint16_t host32bit)
uint16_t ntohs(uint16_t net16bit)
uint16_t ntohl(uint16_t net32bit)
|
参数 | host16bit:主机字节序的16bit数据 |
host32bit:主机字节序的32bit数据 | |
net16bit:网络字节序的16bit数据
|
|
net32bit:网络字节序的32bit数据 | |
返回值 | 成功:返回要转换的字节 |
失败:-1 |
所需头文件 | #include |
函数原型 | int inet_pton(int family,const char *strptr, void *addrptr) |
参数 | family: AF_INET:IPv4协议;AF_INET6:IPv6协议 |
strptr:要转化的值 | |
addrptr:转化后的地址 | |
返回值 | 成功:0 |
失败:-1 |
所需头文件 | #include |
函数原型 | int inet_ntop(int family,void *addrptr, char *strptr, size_t len) |
参数 | family: AF_INET:IPv4协议;AF_INET6:IPv6协议 |
strptr:要转化的值 | |
addrptr:转化后的地址;len:转化后值得大小 | |
返回值 | 成功:0 |
失败:-1 |
struct hostent { char *h_name;/*正式主机名*/ char **h_aliases;/*主机别名*/ int h_addrtype;/*地址类型*/ int h_length;/*地址长度*/ char **h_addr_list;/*指向IPv4或IPv6的地址指针数组*/ };调用该函数后就能返回hostent结构体的相关信息。 getaddrinfo函数涉及到一个addrinfo结构体,如下: struct addrinfo{ int ai_flags;/*AI_PASSIVE,A_CANONNAME*/ int ai_family;/*地址族*/ int ai_socktype;/*socket类型*/ int ai_protocol;/*协议类型*/ size_t ai_addrlen;/*地址长度*/ char *ai_canoname;/*主机名*/ struct sockaddr *ai_addr;/socket结构体/ struct addrinfo *ai_next;/*下一个指针链表*/ }
所需头文件 | #include |
函数原型 | struct hostent *gethostbyname(const char *hostname) |
参数 | hostname :主机名 |
返回值 | 成功:hostent类型指针 |
失败:-1 |
头文件 | #include |
函数原型 | int getaddringo(const *hostname,const char *service,const struct addrinfo *hints,struct addrinfo **result) |
参数 | hostname:主机名 |
service:服务名或十进制的串口字符串 | |
hints:服务线索 | |
result:返回结果 | |
返回值 | 成功:0 |
失败:-1 |
结构体头文件 | |
ai_flags | AI_PASSIVE:该套接口是用作被动的打开 |
AI_CANONNAME:通知getaddrinfo函数返回主机名字 | |
family | AF_INET:IPv协议 |
AF_INET6:IPv6协议 | |
AF_UNSPE:IPv4或IPv6均可: | |
ai_socktype | SOCK_STREAM:字节流套接字socket(TCP) |
SOCK_DGRAM:数据报套接字socket(UDP)
|
|
ai_protocol | IPPROTO_IP:IP协议 |
IPPROTO_IPV4:IPv4协议 | |
IPPROTO_IPV6:IPv6协议 | |
IPPROTO_UDP:UDP协议 | |
IPPROTO_TCP:TCP协议 |
/*getaddrinfo.c*/ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> int main() { struct addrinfo hints, *res = NULL; int rc; memset(&hints,0,sizeof(hints)); /*设置addrinfo结构体各参数*/ hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; /*调用getaddrinfo函数*/ rc = getaddrinfo("127.0.0.1","123",&hints,&res); if(rc != 0) { perror("getaddrinfo"); exit(1); } else printf("getaddrinfo success\n"); }
所需头文件 | #include | |
函数原型 | int socket(int family, int type, int protocol) | |
参数 |
family:
协议族
|
AF_INET:IPv4协议 |
AF_INET6:IPv6协议 | ||
AF_LOCAL:UNIX域协议 | ||
AF_ROUTE:路由套接字 | ||
AF_KEY:密钥套接字 | ||
type:
套接字类型
|
SOCK_STREAM:字节流套接字 | |
SOCK_DGRAM:数据报套接字 | ||
SOCK_RAW:原始套接字 | ||
protocol:0(原始套接字除外) | ||
返回值 | 成功:非负套接字描述符 | |
失败:-1 |
所需头文件 | #include |
函数原型 | int bind(int sockfd,struct sockaddr *my_addr, int addrlen) |
参数原型 | sockfd:套接字描述符 |
my_addr:本地地址 | |
addrlen:地址长度 | |
返回值 | 成功:0 |
失败:-1 |
所需头文件 | #include |
函数原型 | int listen(int socket, int backlog) |
参数原型 | sockfd:套接字描述符 |
backlog:请求队列中允许的最大请求数,大多数系统缺省值为20 | |
返回值 | 成功:0 |
失败:-1 |
所需头文件 | #include |
函数原型 | int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen) |
参数 | sockfd:套接字描述符 |
addr:客户端地址 | |
addrlen:地址长度 | |
返回值 | 成功:0 |
失败:-1 |
所需头文件 | #include |
函数原型 | int connect(int sockfd,struct sockaddr *serv_addr,int addrlen) |
参数 | sockfd:套接字描述符 |
serv_add:服务器地址 | |
addrlen:地址长度 | |
返回值 | 成功:0 |
失败:-1 |
所需头文件 | #include |
函数原型 | int send(int sockfd, const void *msg, int len, int flags) |
参数 | sockfd:套接字描述符 |
msg:指向发送数据的指针 | |
len:数据长度 | |
flags:一般为0 | |
返回值 | 成功:发送的字节数 |
失败:-1 |
所需头文件 | #include |
函数原型 | int recv(int sockfd, void *buf, int len, unsigned int flags) |
参数 |
sockfd:套接字 描述符
|
buf:存放接收数据的缓冲区 | |
len:数据长度 | |
flags:一般为0 | |
返回值 | 成功:接收的字节数 |
失败:-1 |
所需头文件 | #include |
函数原型 | int sendto(int sockfd, const void *msg,int len ,unsigned int flags,const struct sockaddr *to, int tolen) |
参数 | soctfd:套接字描述符 |
msg:指向要发送数据的指针 | |
len:数据长度 | |
flags:一般为0 | |
to:目的机的IP地址和端口信息 | |
tolen:地址长度 | |
返回值 | 成功:发送的字节数 |
失败:-1 |
所需头文件 | #include |
函数原型 | int recvfrom(int sockfd, void *buf,int len, unsigned int flags,struct sockaddr *from,int *fromlen) |
参数 | sockfd:套接字描述符 |
buf:存放接收数据的缓冲区 | |
len:数据长度 | |
flags:一般为0 | |
from:源机的IP地址和端口号信息 | |
fromto:地址长度 | |
返回值 | 成功:接收的字节数 |
失败:-1 |
/*server.c*/ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #define SERVPORT 3333 #define BACKLOG 10 #define MAX_CONNECTED_NO 10 #define MAXDATASIZE 5 int main() { struct sockaddr_in server_sockaddr,client_sockaddr; int sin_size,recvbytes; int sockfd,client_fd; char buf[MAXDATASIZE]; /*建立socket连接*/ if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){ perror("socket"); exit(1); } printf("socket success! sockfd = %d\n", sockfd); /*设置sockaddr_in结构体相关参数*/ server_sockaddr.sin_family = AF_INET; server_sockaddr.sin_port = htons(SERVPORT); server_sockaddr.sin_addr.s_addr = INADDR_ANY; bzero(&(server_sockaddr.sin_zero),8); /*绑定函数bind*/ if(bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } printf("bind success!\n"); /*调用listen函数*/ if(listen(sockfd,BACKLOG) == -1) { perror("listen"); exit(1); } printf("listening...\n"); /*调用accept函数*/ if((client_fd = accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size)) == -1) { perror("accept"); exit(1); } /*调用recv函数接收客户端的请求*/ if((recvbytes = recv(client_fd,buf,MAXDATASIZE,0)) == -1) { perror("recv"); exit(1); } printf("received a connection : %s\n",buf); close(sockfd); }
/*client.c*/ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define SERVPORT 3333 #define MAXDATASIZE 100 int main(int argc,char **argv) { int sockfd,sendbytes; char buf[MAXDATASIZE]; struct hostent *host; struct sockaddr_in serv_addr; if(argc < 2) { fprintf(stderr,"Please enter the sercer‘s hostname!\n"); exit(1); } /*地址解析函数*/ if((host = (struct hostent *)gethostname(argv[1]))==NULL){ perror("gethostname"); exit(1); } /*创建socket*/ if((sockfd = socket(AF_INET, SOCK_STREAM,0)) == -1) { perror("socket"); exit(1); } /*设置sockaddr_in结构体相关参数*/ serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(SERVPORT); serv_addr.sin_addr=*((struct in_addr *)host->h_addr); bzero(&(serv_addr.sin_zero),8); /*调用connect函数主动发起对服务端的连接*/ if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } /*发送消息给服务器*/ if((sendbytes = send(sockfd,"hello",5,0)) == -1){ perror("send"); exit(1); } close(sockfd); }
标签:最大 组成 部分 地址解析 链路 images please 流式 自动
原文地址:http://www.cnblogs.com/ginvip/p/6364303.html