欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux进程通信之Socket(UDP篇)

程序员文章站 2022-06-30 09:14:18
...

1、UDP是无连接不可靠的数据报协议,UDP的常见应用程序是DNS(域名解析系统),NFS(网络文件系统),SNMP(简单网络管理协议);
2、在使用UDP的客户服务器程序中,客户不与服务器建立连接,而是只管使用sendto函数给服务器发送数据报,其中必须指出目标服务器的地址;同样,服务器不接受来自客户的连接,而只是用recvfrom等待指定用户的数据到达,recvfrom将与所接收的数据报一起返回客户的协议地址,因此服务器可以把响应发送给正确的客户!
在UDP服务中,必须先由客户发送数据给服务器,这样服务器才会知道自己在为哪个客户服务
3、流程:
Linux进程通信之Socket(UDP篇)
4、具体代码:server_sock.c

#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define SERVER_PORT  7070
#define SERVER_IP   "192.168.3.66"


int main(int ac, char *av[])
{
    int sockser = socket(AF_INET, SOCK_DGRAM, 0);   //创建服务器端的套接字
    if(sockser == -1){
        perror("socket");
    }

    //设置地址重用
    int y=1;
    setsockopt(sockser, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int));

    struct sockaddr_in addrser, addrcli;    //客户服务器的地址结构体
    addrser.sin_family = AF_INET;    //设置服务器端的协议家族
    addrser.sin_port = htons(SERVER_PORT);  // htons将整型变量从主机字节顺序转变成网络字节顺序,整数在地址空间存储方式变为高位字节存放在内存的低地址处。
    addrser.sin_addr.s_addr = inet_addr(SERVER_IP);  //将一个点分十进制的IP转换成一个长整数型数

    socklen_t addrlen = sizeof(struct sockaddr);   //得到客户服务器的地址长度
    int res = bind(sockser, (struct sockaddr*)&addrser, addrlen);   //绑定服务器的地址信息
    if(res == -1){
        perror("bind");
    }

    char sendbuf[256];
    char recvbuf[256];
    printf("wait cli connect.......\n");
    //收发数据进行服务
    while(1){
        recvfrom(sockser, recvbuf, 256, 0, (struct sockaddr*)&addrcli, &addrlen);    //接收来自目标客户的数据报
        printf("cli:>%s\n", recvbuf);


        printf("Ser:>");
        scanf("%s", sendbuf);
        if(strncmp(sendbuf, "quit", 4) == 0){
            sendto(sockser, sendbuf, strlen(sendbuf) + 1, 0, (struct sockaddr*)&addrcli, addrlen);   //给目标客户发送数据报
            break;
        }
        sendto(sockser, sendbuf, strlen(sendbuf) + 1, 0, (struct sockaddr*)&addrcli, addrlen);
    }

    close(sockser);   //关闭服务器的套接字
    return 0;
}

client_sock.c
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define SERVER_PORT  7070
#define SERVER_IP   "192.168.3.66"


int main(int ac, char *av[])
{
    int sockcli = socket(AF_INET, SOCK_DGRAM, 0);    //得到客户端的套接字
    if(sockcli == -1){
        perror("socket");
    }

    struct sockaddr_in addrser;    //服务器端的地址结构体
    addrser.sin_family = AF_INET;    //设置服务器的地址协议家族
    addrser.sin_port = htons(SERVER_PORT);   //设置服务器的端口号
    addrser.sin_addr.s_addr = inet_addr(SERVER_IP);   //设置服务器的IP地址

    socklen_t addrlen = sizeof(struct sockaddr);   //得到服务器的地址长度

    char sendbuf[256];
    char recvbuf[256];
    printf("cli connect ser ok.\n");
    //收发数据
    while(1){
        printf("Cli:>");
        scanf("%s", sendbuf);
        if(strncmp(sendbuf, "quit", 4) == 0){
            sendto(sockcli, sendbuf, strlen(sendbuf) + 1, 0, (struct sockaddr*)&addrser, addrlen);  //客户端首先发送数据报,为了让服务器确认通信的客户
            break;
        }
        sendto(sockcli, sendbuf, strlen(sendbuf) + 1, 0, (struct sockaddr*)&addrser, addrlen);
        recvfrom(sockcli, recvbuf, 256, 0, (struct sockaddr*)&addrser, &addrlen);   //客户端接收来自服务器的数据报
        printf("Ser:>%s\n", recvbuf);
    }

    close(sockcli);  //关闭客户端套接字
    return 0;
}
相关标签: 进程通信