一.Socket TCP/IP流程图
socket流程图
二.关键数据结构/结构体
sockaddr_in
在列出sockaddr_in结构体之前先将sockaddr结构体说明,此数据结构用作bind、connect、recvfrom、sendto等函数的参数,指明地址信息。sockaddr定义如下:
struct sockaddr {
unsigned short sa_family;
char sa_data[14];
};
但一般编程中并不直接针对此数据结构操作,而是使用另一个与sockaddr等价的数据结构sockaddr_in。
sockaddr_in结构体在<netinet/in.h>中定义,定义如下:
struct sockaddr_in{
short int sin_family;//协议族,在socket编程中只能是AF_INET
unsigned short int sin_port;//存储端口号(使用网络字节顺序)
struct in_addr sin_addr;//存储IP地址,使用in_addr这是数据结构
unsigned char sin_zero[8];//为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节
};
struct in_addr{//实际上就是32位ip地址
unsigned long s_addr;//按照网络字节顺序存储IP地址
};
typedef struct in_addr{
union{
struct{unsigned char s_b1,s_b2,s_b3,s_b4;} S_un_b;
struct{unsigned short s_w1,s_w2;} S_un_w;
unsigned long S_addr;
} S_un;
};
三.socket关键函数
1.socket()
socket()函数原型:
#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain,int type,int protocol);
参数说明:
- domain:协议族,对于socket要使用AF_INET
- type:套接字参数类型,设置为SOCK_STREAM或SOCK_DGRAM。一般使用SOCK_STREAM,因为它是基于TCP的,能保证数据正确传送到对方。SOCK_DGRAM是基于UDP的,无法保证数据正确传送到对方。如果大家使用UDP方式传输,要使用SOCK_DGRAM
- protocol:制定协议。常用协议有IPPROTO_TCP,IPPTOTO_UDP,IPPROTO_SCTP,IPPROTO_TIPC等,它们分别对应TCP,UDP,STCP,TIPC协议。TCP协议传入参数0即可
- 返回值:返回一个套接字描述符,出错返回-1
2.bind()
bind()函数原型:
int bind(int sock_fd,struct sockaddr_in *my_addr, int addrlen);
参数说明:
- sock_fd:套接字,传入的参数是socket()函数的返回值
- my_addr:一个指向包含有本机IP地址及端口号等信息得到sockaddr类的指针
- addrlen:地址长度,传入sizeof(my_addr)即可
- 返回值:成功返回0,失败返回-1;
3.connect()
connect()函数原型:
int connect(int sock_fd, struct sockaddr *serv_addr,int addrlen);
参数说明:
- sock_fd:套接字,传入的参数是socket()函数的返回值
- serv_addr:包含远端主机IP地址和端口号的指针
- addrlen:同上,传入sizeof(serv_addr)即可
- 返回值:成功返回0,失败返回-1
4.listen()
listen()函数原型:
int listen(int sock_fd, int backlog);
参数说明:
- sock_fd:同上,传入的参数时socket()函数的返回值
- backlog:指定在请求队列中允许的最大请求数。进入的连接请求在使用系统调用accept()应答之前要在进入队列中等待。这个值是队列中最多可以拥有的请求的个数。大多数系统的缺省设置为20
- 返回值:成功返回0,失败返回-1