Linux实现简单的udp服务端和客户端(C/C++)

udp_server.cpp

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

static int port = 1997;

int main()
{
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(-1 == sockfd)
    {
        cout << "socket() error" << endl;
        return -1;
    }

    struct sockaddr_in serveraddr, clientaddr;
    socklen_t len = sizeof(struct sockaddr_in);

    memset(&serveraddr, 0, len); // 不建议使用bzero,因为memset跨平台
    memset(&clientaddr, 0, len);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(port);
    // serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); // 可以收到来自任何ip的消息

    if(-1 == bind(sockfd, (struct sockaddr*)&serveraddr, len))
    {
        cout << "bind() error" << endl;
        close(sockfd);
        return -2;
    }

    const int buf_len = 100;
    char buf[buf_len] = { 0 };
    while(1)
    {
        memset(buf, 0, buf_len);
        // 显然这个recvfrom是一个阻塞函数(当然也可以设置成非阻塞的)
        // 在命令行使用 man recvfrom 可得知
        // recv(sockfd, buf, len, flags);
        // 相当于
        // recvfrom(sockfd, buf, len, flags, NULL, NULL);
        // 个人理解如果不关心是哪个ip发过来的消息就可以向上面这么用
        // 第四个参数一般设为0
        if(-1 == recvfrom(sockfd, buf, buf_len, 0, (struct sockaddr*)&clientaddr, &len))
        {
            cout << "recvfrom() error" << endl;
            close(sockfd);
            return -3;
        }
        cout << "client ip: " << inet_ntoa(clientaddr.sin_addr) << endl;
        cout << "client port: " << ntohs(clientaddr.sin_port) << endl;
        cout << "client msg: " << buf << endl;
        cout << endl;

        strcpy(buf, "I am server!");
        // sendto 的第四个参数貌似也常设为0,没有深究
        if(-1 == sendto(sockfd, buf, buf_len, 0, (struct sockaddr*)&clientaddr, len))
        {
            cout << "sendto() error" << endl;
        }
    }

    close(sockfd);
    return 0;
}

udp_client.cpp

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

const int port = 1997;
const char* server_ip = "10.4.64.221";

int main()
{
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(-1 == sockfd)
    {
        cout << "socket() error" << endl;
        return -1;
    }

    socklen_t len = sizeof(struct sockaddr_in);
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, len);

    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(port);
    serveraddr.sin_addr.s_addr = inet_addr(server_ip);

    const int buf_len = 100;
    char buf[buf_len] = { 0 };
    string s;
    while(1)
    {
        // 使用getline来从命令行获得输入是因为即使遇到空格也会当成一个字符串
        // 使用cin则达不到这样的效果
        getline(cin, s);
        strcpy(buf, s.c_str());
        if(-1 == sendto(sockfd, buf, buf_len, 0, (struct sockaddr*)&serveraddr, len))
        {
            cout << "sendto() error" << endl;
            close(sockfd);
            return -2;
        }
        if(-1 == recvfrom(sockfd, buf, buf_len, 0, NULL, NULL))
        {
            cout << "recvfrom() error" << endl;
            close(sockfd);
            return -3;
        }
        cout << "receive from server: " << buf << endl;
    }


    close(sockfd);
    return 0;
}

makefile

.PHONY:all
all:server client

server:udp_server.cpp
	g++ -o $@ $^ -g

client:udp_client.cpp
	g++ -o $@ $^ -g

.PHONY:clean
clean:
	rm -rf server client

直接在命令行输入make即可编译。

你可能感兴趣的:(Linux,C++,udp,linux)