目前毕设要在Linux下做一个类似tomcat的高性能web容器,写这篇文章的时候,大概项目已经写了一小半了。

  前半部分,我都是使用TCP来实现的。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

  目前我要处理的问题是报文处理后需要发送给本地的服务进程,这样的话,使用TCP效率就有点低了,而我对UDP的socket编程又不是特别了解,所以便打算写篇文章记录一下。

  这两个的头文件是自定义的,其他几篇文章有源码。

//      server.cpp
#include "../include/hlib.h"
#include "../include/ErrorSolve.h"

using namespace std;

int main(int argc, char **argv) {
//      指定服务进程的port
        if(argc != 2)
                ErrorSolve::quit("usage: ./server <PORT>");
//      创建UDP套接字
        int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(sockfd < 0)
                ErrorSolve::quit("socket error");
//      初始化服务进程的地址信息
        sockaddr_in servaddr {sin_family:AF_INET, sin_port:htons(atoi(argv[1]))};
        if(inet_pton(AF_INET, "127.0.0.1", (void *)&servaddr.sin_addr) < 0)
                ErrorSolve::quit("inet_pton error");
//      绑定套接字
        if(bind(sockfd, (sockaddr *)&servaddr, sizeof(servaddr)) < 0)
                ErrorSolve::quit("bind error");

        int n;
        char buf[MAXLINE];
//      从sockfd读取,并写入标准输出
        for(;;) {
                if((n = recvfrom(sockfd, buf, MAXLINE, 0, (sockaddr *)NULL, NULL)) < 0)
                        ErrorSolve::quit("recvfrom error");
                buf[n] = '\0';
                //      读到quit,则跳出循环
                if(strcmp("quit", buf) == 0)
                        break;
                printf("%s\n", buf);
        }
        exit(0);
}
//      client.cpp
#include "../include/hlib.h"
#include "../include/ErrorSolve.h"

using namespace std;

int main(int argc, char **argv) {
//    指定服务进程的ip和port
        if(argc != 3)
                ErrorSolve::quit("usage: ./client <IP> <PORT>");
//  创建UDP套接字
        int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(sockfd < 0)
                ErrorSolve::quit("socket error");
//  初始化目的服务进程的地址
        sockaddr_in servaddr {sin_family:AF_INET, sin_port:htons(atoi(argv[2]))};
        if(inet_pton(AF_INET, argv[1], (void *)&servaddr.sin_addr) < 0)
                ErrorSolve::quit("inet_pton error");

        int n;
        char buf[MAXLINE];
//    从标准输入读入,并写给sockfd
        while(~scanf("%s", buf)) {
                if((n = sendto(sockfd, buf, strlen(buf), 0, (sockaddr *)&servaddr, sizeof(servaddr))) < 0)
                        ErrorSolve::quit("sendto error");
                //      读到quit,则跳出循环
                if(strcmp("quit", buf) == 0)
                        break;
                printf("send %d msg\n", n);
        }
        exit(0);
}

这是一个十分简单的服务,客户端向服务端发送消息,服务端接收并将其打印出来。

首先,我们注意到socket函数的第二个参数使用了SOCK_DGRAM,这就表示创建了一个UDP套接字。

然后,会发现在服务端中,与TCP不同的是,我们并没有使用acceptlisten函数,而是直接在主循环中调用recvfrom来接收client发来的报文。

客户端中也没有connect函数,直接使用sendto来向server发送报文。

实际运行程序时,会发现服务端不必在客户端之前运行。客户端直接向指定port发送消息,服务端只需要监听指定端口上是否有消息到来就行了。

确实是感觉效率比TCP高出不少,也不用等待最后的2MSL,不过有什么缺点还得慢慢体会。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄