天天看点

socket之无连接编程(UDP)

UDP是无连接不可靠的数据报协议,UDP的常见应用程序是DNS(域名解析系统),NFS(网络文件系统),SNMP(简单网络管理协议);

在使用UDP的客户服务器程序中,客户不与服务器建立连接,而是只管使用sendto函数给服务器发送数据报,其中必须指出目标服务器的地址;同样,服务器不接受来自客户的连接,而只是用recvfrom等待指定用户的数据到达,recvfrom将与所接收的数据报一起返回客户的协议地址,因此服务器可以把响应发送给正确的客户!!!!

注意:在UDP服务中,必须先由客户发送数据给服务器,这样服务器才会知道自己在为哪个客户服务

编写UDP无连接的客户服务器套接字流程如下:

socket之无连接编程(UDP)

以下是一个UDP实现的客户服务器发送数据报的简单例子:

//服务器端的代码
#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, );   //创建服务器端的套接字
    if(sockser == -){
        perror("socket");
    }

    //设置地址重用
    int y=;
    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);   //设置服务器的端口号
    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 == -){
        perror("bind");
    }

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


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

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


//客户端的代码
#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, );    //得到客户端的套接字
    if(sockcli == -){
        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[];
    char recvbuf[];
    printf("cli connect ser ok.\n");
    //收发数据
    while(){
        printf("Cli:>");
        scanf("%s", sendbuf);
        if(strncmp(sendbuf, "quit", ) == ){
            sendto(sockcli, sendbuf, strlen(sendbuf) + , , (struct sockaddr*)&addrser, addrlen);  //客户端首先发送数据报,为了让服务器确认通信的客户
            break;
        }
        sendto(sockcli, sendbuf, strlen(sendbuf) + , , (struct sockaddr*)&addrser, addrlen);
        recvfrom(sockcli, recvbuf, , , (struct sockaddr*)&addrser, &addrlen);   //客户端接收来自服务器的数据报
        printf("Ser:>%s\n", recvbuf);
    }

    close(sockcli);  //关闭客户端套接字
    return ;
}
           

继续阅读