博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux C socket
阅读量:6312 次
发布时间:2019-06-22

本文共 2981 字,大约阅读时间需要 9 分钟。

  socket套接字和管道同样可以提供进程内通信。但套接字更胜一筹,不同的进程可以跨越不同的主机(说白了,支持网络通信)。使用套接字的知名程序:telnet、rlogin、ftp等。

  你需要知道的一些基本原理:

  使用socket时必须指定通信的类型和协议。

  通信类型决定了以下内容:1、数据传输的基本单元(有的会打包传输,有的作为一个结构体);2、数据是否可丢失,数据传输的可靠性:(有的数据丢失一两个便不可读了,有的数据如视频不受太大影响);3、是一对一的通信还是一对多的通信。

  每一个socket必须有一个命名空间,命名空间一般以PF_开头,AF_开头的符号名指定命名空间的地址格式。

你需要了解的协议内容

  要让两个socket能够通信,必须指定相同的协议。

  协议和命名空间、通信风格是绑定的。比如TCP协议只能用在stream风格的通信中,Internet的命名空间中。对于指定的命名空间,请使用默认协议(不同的协议、命名空间组合可能会出错)

  

SOCKET几种通信风格:

int SOCK_STREAM: 提供可靠的通信方式。有连接。

int SOCK_DGRAM: 和SOCK_STREAM相反,使用的是不可靠通讯方式。无连接,每一个数据包都必须指定地址。一般来说,丢包的时候需要重发数据包。

int SOCK_RAW:  这种风格允许我们访问底层网络协议和接口,一般来讲我们不需要使用这种风格。

 

SOCKET地址:

  实际上Socket地址就是socket的名字。在这里地址和名字是同义词。只有把地址和socket绑定后,我们才可以使用socket通信。

网络接口名:

  每一个网络接口都有个名字如:lo、eth0。但在计算机内部,我们通过索引来使用接口。

#include 
size_t IFNAMESIZE //常量:定义了保存接口名的最大buffer大小。(包含了最后zero 结束字节)
unsigned int if_nametoindex (const char *ifname)//通过接口名返回该接口的索引号,如果不存在该接口名则返回0。也可以用来判断一个接口是否存在。
char * if_indextoname (unsigned int ifindex, char *ifname)//将接口索引号ifindex和接口名ifname映射起来。如果索引无效,返回空指针,否则返回接口名。
struct if_nameindex//用来保存某个接口的信息。/*成员如下:*/unsigned int if_index//接口索引char *if_name//接口名(以NULL结尾)
struct if_nameindex * if_nameindex(void)//返回一个if_nameindex结构体的数组(包含了所有的网络接口)。结束标志:接口索引为0,接口名为空指针。//返回的结构体必须用if_freenameindex释放
void if_freenameindex (struct if_nameindex *ptr)//解释如上

 

本地命名空间:

  符号名为PF_LOCAL。本地命名空间也被称之为Unix域套接字。另外一个名字是file namespace(socket 地址常被实现为文件名)

  本地socket无法被其他机器连接(即便其他机器共享了包含本地socket的文件系统)。其他机器可以共享的文件系统查看到scoket文件,但无法连接。关闭本地命名空间的socket,建议同时删除socket文件。本地命名空间只支持一种协议(不管通信风格),协议号是0。

#include 
int PF_LOCALint PF_UNIXint PF_FILE

以上几个都是宏常量,而且都是同义词。这些常量用来指定本地命名空间。

#incude 
struct sockaddr_un { short int sun_family; char sun_path[108];}

 

sun_family:标志了地址族和socket 地址的格式。在本地命名空间中,使用AF_LOCAL。

sun_path[108]:socket使用的文件名(很奇怪为何是108个字节,理查德·马修·斯托曼推荐使用alloca来申请适当大小的空间存储文件名。并将该数组长度设置为0)

int SUN_LEN(struct sockaddr_un *ptr)

 SUN_LEN是宏定义的函数,用来计算本地命名空间中socket地址的长度。实际为结构体sockaddr_un的大小。

 

创建一个本地socket实例:

#include 
#include
#include
#include
#include
#include
#include
int make_named_socket (const char *filename){ struct sockaddr_un name; int sock; size_t size; /* Create the socket */ sock = socket (PF_LOACAL, SOCK_DGRAM, 0); if (sock < 0) { perror ("socket"); exit (EXIT_FAILURE); } /*Bind a name to the socket.*/ name.sun_family = AF_LOCAL; strncpy (name.sun_path, filename, sizeof (name.sun_path)); name.sun_path[sizeof(name.sun_path)-1] ='\0'; /* The size of the address is the offset of the start of the filename, plus its length (not including the terminating null byte). Alternatively you can just do: size = SUN_LEN(&name); */ size = (offsetof (struct sockaddr_un, sun_path)) + strlen (name.sun_path)); if (bind (sock, (struct sockaddr_un *) &name, size) < 0) { perror ("bind"); exit (EXIT_FAILURE); } return sock;}

 

转载于:https://www.cnblogs.com/san-fu-su/p/5746809.html

你可能感兴趣的文章
spring-通过ListFactory注入List
查看>>
一种基于SDR实现的被动GSM嗅探
查看>>
阿里云ECS每天一件事D1:配置SSH
查看>>
SQL Server 性能调优(性能基线)
查看>>
uva 10801 - Lift Hopping(最短路Dijkstra)
查看>>
[Java Web]servlet/filter/listener/interceptor区别与联系
查看>>
POJ 2312Battle City(BFS-priority_queue 或者是建图spfa)
查看>>
从零开始学MVC3——创建项目
查看>>
CentOS 7 巨大变动之 firewalld 取代 iptables
查看>>
延时任务和定时任务
查看>>
linux下的权限问题
查看>>
教你如何使用Flutter和原生App混合开发
查看>>
Spring Boot 整合redis
查看>>
CSS hover改变背景图片过渡动画生硬
查看>>
JDBC(三)数据库连接和数据增删改查
查看>>
淘宝应对"双11"的技术架构分析
查看>>
订单的子单表格设置颜色
查看>>
Office365 Exchange Hybrid 番外篇 ADFS后端SQL群集(一)
查看>>
9个offer,12家公司,35场面试,从微软到谷歌,应届计算机毕业生的2012求职之路...
查看>>
lvs fullnat部署手册(三)rs内核加载toa篇
查看>>