C TCP socket as not found what I needed in QTCpSocket/QTCPServer
-
Hello, my problem I've asked few topics away is still unresolved. I've found that Qt network API does not solves my problems. Here is what I have to do: a small device of unknown origin transmits to my port
1234
let's say a packet with size of 1060 bytes. I am the PC with the reader socket, and the other side is STM with ARM which in awhile(1)
transmits these 1060 bytes. I don't know the clock of the STM should be around ~200MHz . So what happens? I somehow slow down on the reading of the socket, the STM fills it's buffers and we start losing packets. Here is a simple C program to describe the problem:void TcpServer::init() { Server* s = &Server::Instance(); p_server = s; uint8_t* buffer = nullptr; udp_data_t frame = {0, {0}, {{0}}}; int client, newsocketfd; size_t len; struct sockaddr_in serv_addr, client_addr; if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Error opening socket!"); exit(1); } memset((char*)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(1234); if (bind(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { perror("BIND failed"); exit(1); } listen(socket_fd, 5); client = sizeof(client_addr); static char msg[128] = {0}; // start buffer thread setName("tcp-thread"); create(64 * 1024, 10,TcpServer::worker, this); for(;;) { newsocketfd = accept(socket_fd, (struct sockaddr*)&client_addr, (socklen_t*)&client); if (newsocketfd < 0) { perror("Error on accept"); exit(1); } for(;;) { for(buffer = (uint8_t*)&frame, len = 0; len < sizeof(frame);) { int nn = read(newsocketfd, buffer, sizeof(frame) - len); len += nn; buffer += nn; } printf("%lu\n", (long unsigned int) frame.counter); if (++s->m_conn_info.paketCounter != frame.counter) { s->m_conn_info.paketCounter = frame.counter; snprintf(msg, sizeof(msg), "Missed: %lu\n", (long unsigned int) s->m_conn_info.paketCounter+1); utils::IPC::Instance().sendMessage(msg); } else { m_lock.lock(); m_buffer.enqueue(frame); m_lock.unlock(); } } close(newsocketfd); } close(socket_fd); }
So the second
forever
loop works but somehow fails to read with the speed I expect and the client device stops working as expected, overflows it's buffer and we start losing packets. I've tried with this QTCPSocket but I am very slow running 200 seconds behind the socket. Ex. My counter is 1 000 000 and the device is over 20 000 000 .So any advices?
[Locked as duplicate of https://forum.qt.io/topic/75717/qtcpsocket-bind-and-listen-forever-for-incomming-data-from-a-specific-port ~kshegunov]
-
Hello, my problem I've asked few topics away is still unresolved. I've found that Qt network API does not solves my problems. Here is what I have to do: a small device of unknown origin transmits to my port
1234
let's say a packet with size of 1060 bytes. I am the PC with the reader socket, and the other side is STM with ARM which in awhile(1)
transmits these 1060 bytes. I don't know the clock of the STM should be around ~200MHz . So what happens? I somehow slow down on the reading of the socket, the STM fills it's buffers and we start losing packets. Here is a simple C program to describe the problem:void TcpServer::init() { Server* s = &Server::Instance(); p_server = s; uint8_t* buffer = nullptr; udp_data_t frame = {0, {0}, {{0}}}; int client, newsocketfd; size_t len; struct sockaddr_in serv_addr, client_addr; if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Error opening socket!"); exit(1); } memset((char*)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(1234); if (bind(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { perror("BIND failed"); exit(1); } listen(socket_fd, 5); client = sizeof(client_addr); static char msg[128] = {0}; // start buffer thread setName("tcp-thread"); create(64 * 1024, 10,TcpServer::worker, this); for(;;) { newsocketfd = accept(socket_fd, (struct sockaddr*)&client_addr, (socklen_t*)&client); if (newsocketfd < 0) { perror("Error on accept"); exit(1); } for(;;) { for(buffer = (uint8_t*)&frame, len = 0; len < sizeof(frame);) { int nn = read(newsocketfd, buffer, sizeof(frame) - len); len += nn; buffer += nn; } printf("%lu\n", (long unsigned int) frame.counter); if (++s->m_conn_info.paketCounter != frame.counter) { s->m_conn_info.paketCounter = frame.counter; snprintf(msg, sizeof(msg), "Missed: %lu\n", (long unsigned int) s->m_conn_info.paketCounter+1); utils::IPC::Instance().sendMessage(msg); } else { m_lock.lock(); m_buffer.enqueue(frame); m_lock.unlock(); } } close(newsocketfd); } close(socket_fd); }
So the second
forever
loop works but somehow fails to read with the speed I expect and the client device stops working as expected, overflows it's buffer and we start losing packets. I've tried with this QTCPSocket but I am very slow running 200 seconds behind the socket. Ex. My counter is 1 000 000 and the device is over 20 000 000 .So any advices?
[Locked as duplicate of https://forum.qt.io/topic/75717/qtcpsocket-bind-and-listen-forever-for-incomming-data-from-a-specific-port ~kshegunov]
If I may be brazenly blunt, I really don't feel like reverse engineering your C code, and I really doubt anyone else would embrace the idea either.
Firstly I want to point out that you have bottlenecks that are unrelated to any Qt or non-Qt code. Any TCP/IP controller will "lag" the packets behind and has a maximum throughput, which leads to - second - sending things in and endless non-pausing loop can easily flood the TCP stack, and/or hit the controller(s) throughput limit. And thirdly, it's not exactly clear what you didn't find inQTcpSocket
/QTcpServer
, you never provided any example implementation to dissect, but jumped directly to the berkley sockets implementation.And finally, please have the patience to get answers in your original thread and don't repost questions from it as new threads. If there are no answers for a few days you can gently bump the thread up, by adding a post to the end.