其他分享
首页 > 其他分享> > socket:数据报套接字

socket:数据报套接字

作者:互联网

数据报套接字

一、什么是数据报套接字

二、基于流套接字的客户/服务器的工作流程

1、服务器

与流套接字程序相比:

2、客户端

与流套接字程序相比:

三、套接字接口

1、recvfrom()系统调用

int recvfrom(int sockfd, void *buffer, size_t len,int flags, struct sockaddr *src_from, socklen_t *src_len); 

2、sendto()系统调用

int sendto(int sockfd, void *buffer, size_t len, int flags, struct sockaddr *to, socklen_t tolen);

四、示例

server.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
 
int main(int arc, char **argv)
{
    int server_sockfd = -1;
    socklen_t server_len = 0;
    socklen_t client_len = 0;
    char buffer[512];
    ssize_t result = 0;
 
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
 
    // 创建数据报套接字
    server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 
    // 设置监听的端口、IP
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(9739);
    server_len = sizeof(server_addr);
 
    // 绑定(命名)套接字
    bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);
 
    // 忽略子进程停止 或 退出 的信息,子进程成为僵尸进程后将由内核去管理
    signal(SIGCHLD, SIG_IGN);
 
    while (1)
    {
        // 接收数据,用 client_addr 来储存数据来源程序的IP端口
        // 函数会阻塞知道收到客户端发来的数据
        result = recvfrom(server_sockfd, buffer, sizeof(buffer), 0,
                          (struct sockaddr *)&client_addr, &client_len);
        if (fork() == 0)
        {
            // 利用子进程来处理数据
            buffer[0] += 'a' - 'A';
 
            // 发送处理后的数据
            sendto(server_sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, client_len);
 
            printf("%c\n", buffer[0]);
 
            // 注意,一定要关闭子进程,否则程序运行会不正常
            exit(0);
        }
    }
 
    // 关闭套接字
    close(server_sockfd);
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
#include <netinet/in.h>
#include <arpa/inet.h>
 
int main(int argc, char **argv)
{
    struct sockaddr_in server_addr;
    socklen_t server_len = 0;
    int sockfd = -1;
    char c = 'A';
 
    // 取第一个参数的第一个字符
    if (argc > 1)
    {
        c = argv[1][0];
    }
 
    // 创建数据报套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 
    // 设置服务器IP、端口
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(9739);
    server_len = sizeof(server_addr);
 
    // 向服务器发送数据
    sendto(sockfd, &c, sizeof(char), 0,
           (struct sockaddr *)&server_addr, server_len);
 
    // 接收服务器处理后发送过来的数据,由于不关心数据来源,所以把后两个参数设为0
    recvfrom(sockfd, &c, sizeof(char), 0, 0, 0);
 
    printf("char from server = %c\n", c);
 
    // 关闭套接字
    close(sockfd);
    exit(0);
}

标签:addr,buffer,len,server,sockfd,接字,报套,socket
来源: https://blog.csdn.net/weixin_47803347/article/details/120713254