栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

使用UDP实现本地通信-本地通信的信息结构体sockaddr

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用UDP实现本地通信-本地通信的信息结构体sockaddr

目录
  • 使用UDP实现本地通信
    • socket
    • 本地通信使用的信息结构体
    • UDP本地通信流程
    • 代码实现
      • 服务器---01server.c
      • 客户端---02client.c
    • 执行结果
    • 注意

使用UDP实现本地通信

socket
	#include 

	int socket(int domain, int type, int protocol);
	
参数:
	domain:用于指定通信领域
		   AF_UNIX, AF_LOCAL	本地通信使用
			
	type:指定套接字类型
		  SOCK_DGRAM			UDP协议
	
	protocol:附加协议
			  如果type使用的是  SOCK_STREAM 或者 SOCK_DGRAM
			  此时该参数可以指定为  0
返回值:
	成功  文件描述符
	失败  -1
本地通信使用的信息结构体
struct sockaddr_un {
    sa_family_t sun_family;       
    char        sun_path[108];    
};

sun_path[108] 文件名,执行会自动创建 套节字文件

UDP本地通信流程
服务器:
		创建套接字 socket( )
		填充服务器本地信息结构体 sockaddr_un
		将套接字与服务器本地信息结构体绑定 bind( )
		进行通信 recvfrom( ) / sendto( )	
客户端:
		创建套接字 socket( )
		填充客户端本地信息结构体 sockaddr_un
		将套接字与客户端本地信息结构体绑定 bind() //客户端执行绑定,是为了服务器能获取客户端的信息;如果不绑定 服务器没法回复应答
		填充服务器本地信息结构体 sockaddr_un
		进行通信 sendto( ) / recvfrom( )
代码实现 服务器—01server.c
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#include 
#include 

#define ERRLOG(errmsg)                                       
    do                                                       
    {                                                        
        printf("%s--%s(%d):", __FILE__, __func__, __LINE__); 
        perror(errmsg);                                      
        exit(-1);                                            
    } while (0)

//创建套接字-填充服务器网络信息结构体-绑定
int socket_bind(const char *argv[]);

int main(int argc, const char *argv[])
{
    //创建套接字-填充服务器网络信息结构体-绑定
    int sockfd = socket_bind(argv);

    //用来保存客户端信息的结构体
    struct sockaddr_un client_addr;
    memset(&client_addr, 0, sizeof(client_addr));
    socklen_t client_addr_len = sizeof(client_addr);

    //通信
    char buff[128] = {0};
    while (1)
    {
        //接收应答
        if (-1 == recvfrom(sockfd, buff,sizeof(buff), 0, (struct sockaddr *)&client_addr, &client_addr_len))
            ERRLOG("recv error");
        
        printf("客户端 (%s) 发来数据:[%s]n", client_addr.sun_path, buff);

        //组装回复给客户端的应答
        strcat(buff, "---996");
        //发送数据
        if (-1 == sendto(sockfd, buff, sizeof(buff), 0, (struct sockaddr *)&client_addr, client_addr_len))
            ERRLOG("send error");
        
    }
    //关闭监听套接字  一般不关闭
    close(sockfd);

    return 0;
}

//创建套接字-填充服务器网络信息结构体-绑定
int socket_bind(const char *argv[])
{
    // 1.创建套接字     /本地通信  /UDP
    int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (-1 == sockfd)
        ERRLOG("socket error");
    
    // 2.填充 服务器 网络信息结构体
    struct sockaddr_un server_addr;
    memset(&server_addr, 0, sizeof(server_addr));//清空
    server_addr.sun_family = AF_UNIX;            //本地通信 
    strcpy(server_addr.sun_path, "./my_local");  //套节字文件
    //结构体长度
    socklen_t server_addr_len = sizeof(server_addr);

    // 3.将套接字和网络信息结构体绑定
    if (-1 == bind(sockfd, (struct sockaddr *)&server_addr, server_addr_len))
        ERRLOG("bind error");
    
    return sockfd;
}
客户端—02client.c
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#include 
#include 

#define ERRLOG(errmsg)                                       
    do                                                       
    {                                                        
        printf("%s--%s(%d):", __FILE__, __func__, __LINE__); 
        perror(errmsg);                                      
        exit(-1);                                            
    } while (0)

//创建套接字-填充服务器网络信息结构体-绑定
int socket_bind(const char *argv[]);

int main(int argc, const char *argv[])
{
    //创建套接字-填充服务器网络信息结构体-绑定
    int sockfd = socket_bind(argv);

    // 填充 服务器信息 信息结构体
    struct sockaddr_un server_addr;
    memset(&server_addr, 0, sizeof(server_addr));//清空
    server_addr.sun_family = AF_UNIX;            //本地通信 
    strcpy(server_addr.sun_path, "./my_local");  //套节字文件
    //结构体长度
    socklen_t server_addr_len = sizeof(server_addr);

    //通信
    char buff[128] = {0};
    while (1)
    {
        printf("请输入 : ");
        fgets(buff,sizeof(buff), stdin);
        buff[strlen(buff) - 1] = ''; //清除 n
        
        //发送数据
        if (-1 == sendto(sockfd, buff,sizeof(buff), 0, (struct sockaddr *)&server_addr, server_addr_len))
            ERRLOG("send error");
        
        //接收应答
        if (-1 == recvfrom(sockfd, buff,sizeof(buff), 0, (struct sockaddr *)&server_addr, &server_addr_len))
            ERRLOG("recv error");
        
        printf("服务器应答[%s]n", buff);
    }
    //关闭监听套接字  一般不关闭
    close(sockfd);

    return 0;
}

//创建套接字-填充服务器网络信息结构体-绑定
int socket_bind(const char *argv[])
{
    // 1.创建套接字     /本地通信  /UDP
    int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (-1 == sockfd)
        ERRLOG("socket error");

    //2.填充 客户端自己 网络信息结构体
    struct sockaddr_un client_addr;
    memset(&client_addr, 0, sizeof(client_addr));  //清空
    client_addr.sun_family = AF_UNIX;              //本地通信 
    strcpy(client_addr.sun_path, "./my_local_cli");//套节字文件
    socklen_t client_addr_len = sizeof(client_addr);

    // 3.将套接字和本地信息结构体绑定
    if (-1 == bind(sockfd, (struct sockaddr *)&client_addr, client_addr_len))
        ERRLOG("bind error");
    
    return sockfd;
}
执行结果


注意

1. 客户端侧,不仅 要将 自己的信息 结构体 与 sockfd套接字 绑定 ;还得 填充 服务器信息 信息结构体

填充 服务器信息 信息结构体 :以便于发送数据
sendto (sockfd, buff,sizeof(buff), 0, (struct sockaddr *)&server_addr, server_addr_len))

2. 报错 :bind error: Address already in use
因为已经执行一次 套节字文件 已经存在
所以 只需要删除 套节字文件 即可

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/939949.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号