-1

Is there a possibility to improve this function for faster execution (even microseconds matter) according to the server rules?

How can non-blocking help me in this situation? Execution is less than the other connection attempt is possible. Can non-blocking help in this situation, and how can I ensure how much to wait between connections?

The point is the fastest time from socket creation to read received. And as many connections per second as possible.

Server rules/limitations:

  • 1 connection every 12 milliseconds. If you break this rule and try to connect earlier, IP is blocked for 1200 milliseconds.
  • Connection is closed every time read is received.
int main()
{
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);

    while(1)
    {
     clock_gettime(CLOCK_MONOTONIC, &end);
     int elapsed_us = diff_us(end, start);

     // wait until 12ms
     if (elapsed_us < 12000)
     {
         usleep(12000-elapsed_us);
     }

     // check
     clock_gettime(CLOCK_MONOTONIC, &start);
     if (allowed(request)==1)
     {
         dojob();
         return(0);
     }
    }

    return 0;
    }

    int allowed(char request[])
    {

    char server_message[4096];
    memset(server_message,'\0',sizeof(server_message)); 

    int socket_desc = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.s_addr = inet_addr(server);

    connect(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr));
    write(socket_desc, request, strlen(request));
    read(socket_desc, server_message, sizeof(server_message));
    
    close(socket_desc);
    char * ret = strstr(server_message, "OK");

    if (ret)
        return 1; // granted, do the job
    else
    {
        uwait(10000);
        return 0; // come back later, repeat asking for the allowance to do the job
    }
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Aer
  • 49
  • 1
  • 12
  • 2
    please show a [mre] – stark Nov 01 '22 at 22:14
  • You don't need to connect again if server don't close connection. If `read()` return 0 it means server closed connection. What application layer protocol do you try to use? HTTP? Maybe you want keepalive? – dimich Nov 01 '22 at 22:47
  • Sounds like someone urgently needs [a good reference book](https://en.wikipedia.org/wiki/UNIX_Network_Programming). – tadman Nov 01 '22 at 22:49
  • I'd also say if you're looking for absolute performance, forget traditional UNIX sockets and use [ZeroMQ](https://zeromq.org). – tadman Nov 01 '22 at 22:50
  • This is very abstract. Can you explain what exactly are you communicating with? `I understand that the main thing` Why? How do you "understand that"? Have you profiled it? Why not change the server to send a notification to you when "it" is possible? `Socket must be blocking because you cannot connect asynchronously` I do not understand. Why does "wait for answer" means that _your_ socket can't be asynchronous? `if i repeat write-read without using connect once again, i get an empty message from server` Why not fix the server? – KamilCuk Nov 02 '22 at 12:21
  • Have you implemented the server? If you have, changing its behavior would be the easiest way to improve performance. – VLL Nov 02 '22 at 12:23
  • `Is it possible to use alternative functions in order to increase performance (every microseconds matters)?` Great - so have you profiled your program that context switch between user space and kernel space takes the most time? `How to check if server really closed connection after read() ?` https://stackoverflow.com/questions/17705239/is-there-a-way-to-detect-that-tcp-socket-has-been-closed-by-the-remote-peer-wit – KamilCuk Nov 02 '22 at 12:23
  • Hi. I added code and algorithm. Server not implemented by me and cannot be changed. I have the rules and i have to play according to server rules. I try to put my client server in the best possible location for network latency and to have the best code and OS for the performance. I use Ubuntu 20.04.5 and C and this code. And looking is there are any possibilities to improve. – Aer Nov 02 '22 at 12:34
  • You don't even check return value from `read()`. How do you know *i get an empty message from server.*? – dimich Nov 02 '22 at 13:42
  • Because i did many tests and tried that. – Aer Nov 02 '22 at 17:32
  • @Aer Even If server sends two chars "OK" you may receive one byte "O" (`read()` return 1) then one byte "K". But anyway, if server closes connection after sending response by design and if protocol don't implement some kind of keepalive, you cannot "optimize" it on client side. You can try to forward TCP connection from UDP on server side, e.g. with `socat UDP-LISTEN:... TCP-CONNECT:...`, this will move TCP SYN/ACK to local connection and may improve latency at the cost of reliability, but may somehow work only for short messages due to TCP fragmentation. – dimich Nov 02 '22 at 19:09
  • [Beej's Guide to Network Programming](https://beej.us/guide/bgnet/) provides *Current* approaches to network communications you may benefit from. – David C. Rankin Nov 03 '22 at 00:29
  • Lots of broken premises here. Refrain from making factual statements about that which you're still learning, because you don't know if they're factual or not. Of course it's possible to `connect` (portably, even) without blocking. All of this was explored decades ago, and the fact that you would ask it as though it's a unique question, with broken premises to boot, is utterly baffling. Is the only thing that matters in your world your own empirical evidence, which leads you astray? Or are you willing to read [what experts write](http://www.kegel.com/c10k.html)? **More reading, less guessing.** – autistic Nov 05 '22 at 22:30
  • I tried and edited once again. – Aer Nov 06 '22 at 18:09

1 Answers1

0

I see two things that are killing the performance of your program.

  1. The memset for each iteration, you don't need to, read gives you the number of bytes read.
  2. The creation of the socket and the connection.

From my point of view you should focus on that, however is not clear to me whats the intend of your program, some homework may be? also is missing whats the function do_job does

camp0
  • 372
  • 1
  • 5