TCP/IP网络编程-系统调用

网络编程相关API

1. socket() 创建套接字

2. bind() 绑定本机地址和端口

3. connect() 建立连接

4. listen() 设置监听套接字

5. accept() 接收TCP连接

6. recv(),read(),recvfrom() 数据接收

7. send(),write(),sendto() 数据发送

8. close(),shutdown()关闭套接字

1. socket() 创建套接字

头文件  #include<sys/types.h>       

#include<sys/socket.h>

函数原型 int socket (int domain, int type, intprotocol);

功能:根据type 创建某个类型的 套接字,类似于文件io的open();

参数:intdomain   协议类型   一般使用PF_INET或AF_INET

inttype      套接字类型,如下 

a)    SOCK_STREAM   // 流式套接字

b)    SOCK_DGRAM   // 数据报套接字

c)    SOCK_RAW      //  原始套接字

 int protocol  一般设置为0

返回值:成功:返回一个套接字描述符,和文件描述符统一编号

              失败:-1

 

2. bind() 绑定本机地址和端口

补充知识点:

通用地址结构:

Struct sockaddr

{

u_short  sa_family;   // 地址族, AF_xxx

char  sa_data[14];     // 14字节协议地址

};

Internet协议地址结构:

structsockaddr_in    

{          

u_short sin_family;      // 地址族, AF_INET,2 bytes

u_short sin_port;      // 端口,2 bytes  【填充的时候要转换字节序】

struct in_addr sin_addr;  //IPV4地址,4 bytes

char sin_zero[8];        // 8bytes unused,作为填充 不同

};

 

 

 

IPV4地址结构

//internetaddress

structin_addr

{

in_addr_t  s_addr;            // u32 network address

};

in_addr_t  等价于 unsigned int

 

      

函数1:u_short htons (u_short short),主机字节序到网络字节序端口号转换函数(博文:TCP/IP网络编程基础知识有介绍)

函数2:in_addr_t inet_addr(const char *strptr);将strptr所指的字符串转换成32位的网络字节序二进制值。例如将ip地址:192.168.1.245->0xc0a801f5

注意:这个函数为什么没有像端口号那样需要一个字节序转换函数,因为这个函数顺便把字节序转换了。

 

bind()函数

头文件  #include<sys/types.h>         

#include <sys/socket.h>

函数原型int bind(int sockfd, const structsockaddr *addr,socklen_t addrlen);

功能: 绑定ip+port

目的: 进程 +ip  + port + sockfd  形成一个集合

参数: int sockfd,由socket() 调用返回

const struct sockaddr *addr ,addr是指向sockaddr_in结构的指针,包含本机IP地址和端口号

struct sockaddr_in               

u_short sin_family;      // 地址族, AF_INET

u_shortsin_port;      // 端口号

struct in_addrsin_addr;  // IPV4地址,4 bytes

socklen_t addrlen:           sizeof(struct sockaddr)

返回值:成功0  失败 -1

举例:

struct sockaddr_in   my_addr;

my_addr.sin_family = PF_INET;    

my_addr.sin_port  = htons (6666); 

my_addr.sin_addr.s_addr =inet_addr(“192.168.1.245”);   

addrlen = sizeof(struct sockaddr_in)

 

bind(socketfd, (struct sockaddr*)(&my_addr), addrlen);

注:struct sockaddr是通用的套接字地址是非常早期的socket中bind中使用的参数,一直被保留下来,而struct sockaddr_in则是internet环境下套接字的地址形式,是现在socket实际使用的参数,二者长度一样,都是16个字节,所以两者可以进行强制转化且达到不丢失数据目的。

 

3. connect() 建立连接

头文件 #include <sys/types.h>    

      #include <sys/socket.h>

函数原型 int connect(intsockfd, const struct sockaddr *addr,socklen_t addrlen);

功能: 客户端 主动连接服务器,实际上会和服务器进行3次握手(后面博文会讲)

参数: int sockfd

struct sockaddr *addr  这里填服务器的ip+port ,而自己的端口,os会自动分配,ip地址 os 自动帮我找到

socklen_t addrlen sizeof(struct sockaddr_in)

返回值:成功0  失败-1

注:connect()是客户端使用的系统调用

4. listen() 设置监听套接字

头文件 #include <sys/types.h>      

      #include <sys/socket.h>

函数原型int listen (int sockfd, int backlog);

功能:让该套接字开启监听功能

注:该函数执行完,sockfd就变成了监听套接字,只能用来接收客户端的连接,不能用来收发数据。内核启动线程,专门用于处理客户端连接的,先把客户端放到一个队列中,要向真正和该客户端通信起来,要调用accept函数

参数:int sockfd      

int backlog    接收多少个客户端的连接

5. accept() 接收TCP连接

头文件 #include <sys/types.h>   

      #include <sys/socket.h>

函数原型int accept(int sockfd, struct sockaddr*addr, socklen_t *addrlen);

功能:从队列中,提取一个客户端,创建新的套接字用于和该客户端真正的通信

参数:int sockfd  监听套接字

struct sockaddr *addr      客户端的ip+port

 socklen_t *addrlen         struct sockaddr 大小

返回值:成功: 新的套接字,服务器真正和客户端 通信 收发数据,就是通过这个套接字,不再使用监听套接字

              失败:-1

6. recv(),read(),recvfrom() 数据接收

7. send(),write(),sendto() 数据发送

8. close(),shutdown()关闭套接字

read()/write()/close()是文件IO中函数,其余函数以后再补充。

 


猜你喜欢

转载自blog.csdn.net/weixin_42048417/article/details/80460913