I want to console every time I receive it on a UDP socket.

Asked 1 years ago, Updated 1 years ago, 441 views

Creating UDP sockets in C++.
The current one is that the server stores messages in a buffer and displays them all together. I'd like to display them on the console every time I receive them for debugging. I'd like to know how to modify the code below to achieve this.

Environment: Ubuntu 20.04

Source Code

server.cpp

#include<stdio.h>
# include <string.h>
# include "udp_socket.hpp"
# include <unistd.h>

constint PortNumber = 50000; // 49152 through 65535
const char*IPaddress="172.0.0.1"; // recv side ip

const int recv_max_size = 10;
const int64_t timeout_setting=10;

int main(intargc, char**argv){
    UDPSocket udp0 (IPaddress, PortNumber);

    udp0.udp_bind();

    for(inti=0;i<recv_max_size;i++){
        if(udp0.timeout(timeout_setting)==0){
            error("time out";
            break;
        }
        std::string data=udp0.udp_recv();
        printf("%s\n", data.c_str());
    }

    return 0;
}

udp_socket.hpp

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

class UDPSocket {
    intsock;
    structure sockaddr_inaddr;
public:
    UDPSocket (std::string address, int port) {
        sock=socket(AF_INET, SOCK_DGRAM, 0);
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=inet_addr(address.c_str());
        addr.sin_port = htons(port);
    }
    void udp_send(std::string word) {
        sendto(sock, word.c_str(), word.length(), 0, (struct sockaddr*)&addr,sizeof(addr));
    }

    void udp_bind(){
        bind(sock,(construct sockaddr*)&addr,sizeof(addr)));
    }

    int timeout(int64_tsec){
        FD_ZERO(&readfds);
        FD_SET(sd, & readfds);
        tv.tv_sec=sec;
        return select(sd+1,&readfds,NULL,NULL,&tv);
    }

    std::string udp_recv(){
        #define BUFFER_MAX400
        char buf [BUFFER_MAX];
        memset(buf,0,sizeof(buf));
        recv(sock, buf, sizeof(buf), 0);
        return std:string(buf);
    }
    void udp_recv(char*buf, int size){
        memset(buf,0,size);
        recv(sock, buf, size, 0);
    }

    ~UDPSocket(){
        close(sock);
    }
private:
    intsd;
    structure sockaddr_inaddr;
    socklen_tsin_size;
    structure sockaddr_in from_addr;
    fd_set readfds;
    structure timeval tv;
};

Below is the log of sendto to the current server.
close and then write. I want to do write every time I do recvfrom.

11:38:10.804218 select (9,[8], NULL, NULL, {tv_sec=140262861, tv_usec=519539})=1 (in[8], left {tv_sec=140262859, tv_usec=184927})<2.334631>
11:38:13.139160 recvfrom (8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")}, [32657->16] = 11<0.000007>
11:38:13.139263fstat(1,{st_mode=S_IFIFO|0600,st_size=0,...}) = 0<0.000009>
11:38:13.139312 select (9, [8], NULL, NULL, {tv_sec=5, tv_usec=184927}) = 1 (in [8], left {tv_sec=4, tv_usec=682655}) <0.502286>
11:38:13.641707 recvfrom (8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000011>
11:38:13.641792 select(9,[8], NULL, NULL, {tv_sec=5, tv_usec=682655})=1(in[8], left {tv_sec=4, tv_usec=745982})<0.936685>
11:38:14.578538 recvfrom(8, "hello wold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000007>
11:38:14.578597 select (9, [8], NULL, NULL, {tv_sec=5, tv_usec=745982}) = 1 (in [8], left {tv_sec=5, tv_usec=478603}) <0.267391>
11:38:14.846041 recvfrom (8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000007>
11:38:14.846098 select (9, [8], NULL, NULL, {tv_sec=5, tv_usec=478603}) = 1 (in [8], left {tv_sec=5, tv_usec=278146}) <0.200496>
11:38:15.046662 recvfrom (8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000008>
11:38:15.046730 select (9,[8], NULL, NULL, {tv_sec=5, tv_usec=278146}) = 1 (in[8], left {tv_sec=2, tv_usec=754525}) <2.523639>
11:38:17.570431 recvfrom (8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000011>
11:38:17.570497 select (9,[8], NULL, NULL, {tv_sec=5, tv_usec=754525}) = 1 (in[8], left {tv_sec=4, tv_usec=82849}) <1.671736>
11:38:19.242312 recvfrom (8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000008>
11:38:19.242372 select (9,[8], NULL, NULL, {tv_sec=5, tv_usec=82849}) = 1 (in[8], left {tv_sec=3, tv_usec=527405}) <1.555459>
11:38:20.797890 recvfrom (8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000008>
11:38:20.797968 select(9,[8], NULL, NULL, {tv_sec=5, tv_usec=527405})=1(in[8], left {tv_sec=3, tv_usec=153375})<2.374050>
11:38:23.172093 recvfrom (8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000010>
11:38:23.172182 select (9,[8], NULL, NULL, {tv_sec=5, tv_usec=153375}) = 1 (in[8], left {tv_sec=2, tv_usec=996190}) <2.157256>
11:38:25.329508 recvfrom(8, "hellowold", 1500, 0, {sa_family=AF_INET, sin_port=htons(51618), sin_addr=inet_addr("127.0.0.1")} ,[16]) = 11<0.000008>
11:38:25.329580 close(8) = 0<0.000016>
11:38:25.329626 write (1, "hellowold\nhellowold\nhellowo" ..., 120) = 120<0.000012>
11:38:25.329682 exit_group(0)=?
11:38:25.329806++++exited with 0++++

c++ linux c

2022-11-24 11:07

1 Answers

Now I understand the meaning of the question.

 std::string data=udp0.udp_recv();
printf("%s\n", data.c_str());

Is it a question about the behavior of stdout that says printf is called every time, but it doesn't output for some reason? If so, UDP is totally irrelevant.Please ask the appropriate questions.

The reason is that it is buffered.where buffering defaults to setvbuf(3)

Normal all files are block buffered.If a stream references to a terminal (as stdout normally does), it is line buffered.The standard error stream stderr is always buffered by default.

There was an explanation that

  • Block buffering files
  • stdout buffered rows
  • stderr does not buffer

"%s\n" contains a new line, so line buffering is done, but should appear each time.Is it because redirects, pipes, etc. are not output directly to the console and are block buffered?

The solution is

setvbuf(stdout, NULL,_IOLBF, 0);

and line buffering?


2022-11-24 21:36

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.