『网安产品开发实践』Linux编程-简单UDP Socket通信程序

104 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

套接字基础

在这里插入图片描述

套接字类型

Linux支持多种套接字类型,即应用程序希望的通信服务类型

  • SOCKET_STREAM:双向可靠数据流,对应TCP
  • SOCKET_DGRAM :双向不可靠数据报,对应UDP
  • SOCKET_RAW:是低于传输层的低级协议或物理网络提供的套接字类型,可以访问内部网络接口。例如接收和发送ICMP报文

UDP Socket编程的过程

在这里插入图片描述 实现UDP套接字基本步骤分为服务器端和客户端两部分:

服务器端:

  • 创建套接字;
  • 绑定套接字;
  • 读取客户端发过来的数据;
  • 向客户端写数据;
  • 关闭套接字。

客户端:

  • 创建套接字;
  • 向服务器发送数据;
  • 读取服务器发来的数据;
  • 关闭套接字。

适用范围

部分满足以下几点要求时,应该用UDP:

  • 面向数据报
  • 网络数据大多为短消息
  • 拥有大量Client 对数据安全性无特殊要求
  • 网络负担非常重,但对响应速度要求高

源码

gcc编译后使用

gcc -o udps udps.c
gcc -o udpc udpc.c
./udps
./udpc

server

// udps.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#define PORT 8900
#define MAXSIZE 1024

int main(){
    
    struct sockaddr_in client_addr;
    struct sockaddr_in server_addr;
    char send_buf[MAXSIZE];
    char recv_buf[MAXSIZE];
    socklen_t len;
    int recvnum;
    int sockfd;

    if(-1==(sockfd = socket(AF_INET, SOCK_DGRAM, 0))){
        perror("create error!\n");
        return -1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);

    if(-1==bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr))){
        perror("bind error!\n");
        return -1;
    }

    while(1){
        memset(recv_buf, 0, MAXSIZE);
        memset(send_buf, 0, MAXSIZE);
        len = sizeof(client_addr);
        
        if(-1==(recvnum = recvfrom(sockfd, recv_buf, MAXSIZE, 0, (struct sockaddr*)&client_addr, &len))){
            perror("receive error!\n");
            return -1;
        }
        printf("client:[%dB]%s\n", strlen(recv_buf), recv_buf);
        
        sprintf(send_buf, "[%dB]%s\n", strlen(recv_buf), recv_buf);
        sendto(sockfd, send_buf, MAXSIZE, 0, (struct sockaddr*)&client_addr, len); 
    }

    close(sockfd);
    return 0;
}

client

// udpc.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#define PORT 8900
#define MAXSIZE 1024

int main(){
    int sockfd;
    socklen_t len;
    struct sockaddr_in client_addr;
    struct sockaddr_in server_addr;
    char send_buf[MAXSIZE];
    char recv_buf[MAXSIZE];
 
    if(-1==(sockfd = socket(AF_INET, SOCK_DGRAM, 0))){
        perror("create error!\n");
        return -1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);


    while(1)
    {  
        len = sizeof(server_addr);
        
        memset(send_buf, 0, MAXSIZE);
        memset(recv_buf, 0, MAXSIZE);
        
        printf("client:");
        gets(send_buf);
        
        sendto(sockfd, send_buf, MAXSIZE, 0, (struct sockaddr*)&server_addr, len);
        
        recvfrom(sockfd, recv_buf, MAXSIZE, 0, (struct sockaddr*)&client_addr, &len);
        printf("server:%s\n",recv_buf);

    }

    close(sockfd);
    return 0;
}

运行样例

server会返回接收到的信息和大小 在这里插入图片描述