socket函数使用方法

Socket原理及创建

在Linux网络编程模型中,套接字(Socket)用来表示一个网络连接,可以是TCP连接,也可以是UDP连接,在网络通信过程中不管是写数据还是读数据都要通过Socket来完成,因此Socket是网络通信中非常重要的一个工具。下面我们来分析一下Socket的工作原理和创建的过程。

原理说明

在Linux系统中,Socket可以作为一种进程间通信的机制,可以用于不同主机的不同进程之间的通信和数据交换。Linux内核为这一机制提供了一组应用程序接口(API),称为套接字接口(socket API)。应用程序可以通过套接字接口,来使用网络套接字,以进行数据交换。Socket在程序中可以用一个封装好的结构体类型来表示,该结构体主要包含了下面的五个字段:

Socket结构体字段 字段的含义
使用的协议族 可以选择TCP、UDP、本地通信等
本机IP地址 用于表示本机地址
本机端口 用于表示本机参与通信的进程
远程服务器IP地址 用于表示远程服务器
远程服务器端口 用于表示远程服务器参与通信的进程

在套接字接口中,以IP地址及通信端口组成套接字地址。远程的套接字地址,以及本地的套接字地址完成连接后,再加上使用的协议,这个五元组,作为套接字对,之后就可以彼此交换数据。

Socket的创建

在实际通信过程中,不管是客户端还是服务器都需要先初始化一个套接字,然后再进行后续操作,Linux内核提供的Socket API中有一个socket函数可以完成这件事,其函数原型如下所示:

1
int socket(int domain,int type,int protocol);//用于创建Socket实例

该函数有三个参数,均为int类型,但是它们有各自的含义,下面我们针对这三个参数进行分析:

  • domain参数
    该参数表示创建Socket所使用的协议域,也称为协议族,协议族决定了socket的地址类型,在通信中必须采用对应的地址。该参数的可能取值如下所示:

    (1) AF_INET :表示使用IPV4协议

    (2)AF_INET6 : 表示使用IPV6协议

    (3) AF_UNIX:表示只在本机内通信的套接字

    通常我们设置该参数为AF_INET,表示使用IPV4协议进行通信,AF_INET本质上是内核源码中定义的一个宏#define AF_INET 2,正好与上面函数原型指定的int类型。

  • type参数

    type参数指定套接字的具体类型,该参数决定了Socket的类型,可能取值如下所示:

type参数可能取值 取值的具体含义
SOCK_DGRAM 创建UDP数据报套接字,使用不连续不可靠的连接
SOCK_STREAM 创建TCP流套接字,使用稳定可靠的连接
SOCK_RAW 创建原始套接字。提供原始网络协议存取
SOCK_PACKET 与网络驱动程序直接通信
SOCK_SEQPACKET 提供连续可靠的数据包连接
SOCK_RDM 提供可靠的数据包连接

在实际编程时,我们可以根据自己的需要指定其中一个参数来选择创建的Socket类型。

  • protocol参数
    protocol参数指定了Socket所使用的协议,常用的字段有:IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。通常情况下设置为0,通过参数domain指定的协议族和参数type指定套接字类型来确定参数。当创建原始套接字,系统无法惟一的协议,这时候就要使用该参数来指定协议。

注意:并不是上面的type和protocol可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择type类型对应的默认协议。

函数的使用

使用该函数需要在程序中包含两个头文件,如下所示

1
2
#include <sys/types.h>
#include <sys/socket.h>

该函数返回一个int类型的值,如果函数执行成功则返回一个大于0的数,表示一个套接字描述符,可以用来索引一个套接字(类似于文件描述符),在后续的操作中可以使用该描述符来查找套接字并对其进行操作。如果函数执行失败,则返回-1。

参考文章

https://blog.csdn.net/bian_qing_quan11/article/details/71713647