socket、sockaddr_in和sockaddr的区别

socket、sockaddr_in和sockaddr的区别

在实现简单的服务器端和客户端的通信中,对于服务器端来说,通信的过程是:

  • 通过socket函数来创建套接字(相当于网络接口)
  • 调用bind函数为其套接字分配ip地址和端口号
  • 调用listen函数将套接字转为可接受连接的状态
  • 调用accept函数来受理可能发来的连接请求
  • 调用write函数来传输数据

对于客户端来说,通信的过程概括为如下:

  • 通过socket函数来创建套接字(相当于网络接口)
  • 调用connect函数,使之成为客户端套接字,向服务器端发出连接请求

客户端和服务器端都有创建套接字的过程,是通过第二步调用的函数才能确定这是属于服务器端的socket还是客户端的socket。socket创建之后相当于linux中的文件描述符(此处的定义和打开文件一样,相当于分配了一个编号)

以客户端的代码为例,创建socket的过程大致如下:

int sock;
struct sockaddr_in serv_addr;
char message[30];
int str_len;
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1)
    error_handling("socket error()");
//此时只创建了一个socket,但是还没有分配
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_Addt(argv[1]);	//argv是命令行参数的数组
serv_addr.sin_port = htons(atoi(argv[2]));

其中出现了socket、sockaddr_in、以及sock_addr的概念,故对此做一些辨析。

1. socket

socket即套接字,在网络编程中相当于是在端对端的通信中创建了一种网络接口,一般是通过ip传输到指定的主机,但是主机可能同时有视频、网页等等多个进程需要建立网络连接,因此操作系统收到socket之后通过端口号来区分下一步需要分配给哪个端口对应的进程(tcp和udp可以用同一个端口号)

因此,socket本质上是进行通信的最终载体。
socket创建的时候通过socket()函数来进行,第一个参数表示选择协议族信息,pf_inet表示是ipv4协议族,第二个参数表示数据传输方式,这里表示字节流的方式,即TCP。第三个参数是指定具体协议信息。

在通信结束之后,需要调用close函数来关闭套接字。

2. sockaddr_in

sockaddr_in是结构体类型,定义如下:

struct sockaddr_in
{
    sa_family sin_family;	//地址族
    uint16_t sin_port;		//16位tcp/udp端口号
    struct in_addr sin_addr;	//32位ip地址,in_addr同样是结构体变量
    char sin_zero[8];		//不使用	共8字节
}

为了给socket命名和使其使用,服务器需要给socket绑定对应的ip和端口号,这样socket才可以投入使用。

3. sock_addr

sock_addr是sockaddr_in的一种集成,对于sockaddr_in来说,包含所有的端口号、ip、地址族等信息,而sockaddr只有sa_family以及char sa_data[14];
sa_data[14]集成了sockaddr_in里面所有的信息。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值