本地套接字 [补档-2023-07-24]

发布时间 2024-01-13 18:14:08作者: 小白同学_C

本地套接字

7-1简介

​ 在Linux系统下,可以使用本地套接字(Unix域套接字)进行进程间通信。本地套接字是一种特殊类型的套接字,用于在同一主机上的进程之间进行通信。

7-2 创建本地套接字服务器的流程

​ 可以使用TCP或UDP的方式来实现通信,使用TCP就得遵循TCP的流程,UDP就要遵循UDP的流程。

7-2-1使用TCP的本地套接字服务器流程

第一步:使用socket创建一个套接字,并且第一个参数为AF_UNIX,第二个为SOCK_STREAM (TCP)。

第二步:使用bind进行本地地址绑定,但是结构体要是struct sockaddr_un并且成员sun_family也要是AF_UNIX。而且要创建一个变量(详见代码)。然后bind中要使用struct sockaddr_un &进行强转

第三步:使用listen函数监听套接字。

第四步:使用accept函数获得新连接。

第五步:对接收到的数据进行读写或者其他操作。

第六步:如果不需要停下来记得关闭acdept和socket创建的两个文件描述符。

7-2-2使用TCP的本地套接字客户端流程

第一步:创建套接字,并且第一个参数为AF_UNIX,第二位SOCK_STREAM (TCP)。

第二步:绑定本地地址。(不是必须的, 若无显示绑定会进行隐式绑定,但服务器不知道谁连接了)。

第三步:调用connect函数进行连接。

第四步:通信。

第五步:关闭第一步创建的描述符。

7-3 本地套接字服务端代码实例

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/un.h>

 
int main()

{

  //创建套接字,记得使用AF_UNIX

  int lfd = socket(AF_UNIX, SOCK_STREAM, 0);

  if (lfd < 0) {

​    perror("创建套接字失败!");

​    exit(0);

  }

 

  struct sockaddr_un serv;//本地地址

  struct sockaddr_un clie;//客户端地址

  serv.sun_family = AF_UNIX;//记得使用UNIX

  //创建一个变量,之后客户端需要访问这个变量才能进行本地通信

  strcpy(serv.sun_path, "./server.sock");

 

  //绑定

  int ret = bind(lfd, (struct sockaddr*)&serv, sizeof(serv));

  if (ret < 0) {

​    perror("bind error");

​    exit(0);

  }

 

  //监听

  ret = listen(lfd, 10);

​    if (ret < 0) {

​      perror("listen error");

​      exit(0);

​    }

 

  int n;

  char data[100];

  char serv_data[100] = "server susser!";

  //建立连接

  int len = sizeof(clie);

  int cfd = accept(lfd, (struct sockaddr*)&clie, &len);

 

  while (1) {

​    memset(data, 0x00, sizeof(data));

​    n = recv(cfd, data, sizeof(data), 0);

​    if (n < 0) {

​      perror("recv error!!!");

​    }

 

​    if (send(cfd, serv_data, sizeof(serv_data), 0) == -1) {

​      perror("send error!!!");

​    }

  

  }
 

  close(lfd);

​    return 0;

}

7-4 本地套接字客户端代码实例

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/un.h>
 

int main()

{

  //创建套接字,使用AF_UNIX

  int cfd = socket(AF_UNIX,SOCK_STREAM,0);

 

  //绑定

  struct sockaddr_un clie;

  bzero(&clie, sizeof(clie));//类似于memset

  clie.sun_family = AF_UNIX;//同样使用AF_UNIX

  strcpy(clie.sun_path, "./client.sock");//创建变量

  int ret = bind(cfd, (struct sockaddr*)&clie, sizeof(clie));//绑定

  if (ret < 0)

  {

​     perror("bind error");

​     return -1;

  }

  int data[100];

  int n;

 

  //监听

  ret = listen(cfd, 123);

  if (ret < 0) {

​     perror("error");

​     exit(0);

  }

 

  struct sockaddr_un serv;//用于记录服务端地址

  bzero(&serv, sizeof(serv));//类似于memset

  serv.sun_family = AF_UNIX; //同样使用AF_UNIX

  strcpy(serv.sun_path,"./server.sock");//创建变量

 

  //连接

  ret = connect(cfd,(struct sockaddr *)&serv,sizeof(serv));

  if (ret < 0) {

​     perror("error");

​     exit(0);

  }

 

  while (1) {

​     memser(data,0x00,sizeof(data));//初始化

​     printf("请输入你要发送的数据\n");

​     scanf("%s", &data);

 

​     if (send(cfd, data, sizeof(data), 0) == -1) {

​       printf("发送数据失败\n");

​       return -1;

​     }

 

​     n = recv(cfd,data,sizeof(data),0);

​     printf("%s\n",data);

  }

  

  close(cfd);

}