Russian Qt Forum
Апрель 07, 2020, 19:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: IPC (AF_UNIX Socket)  (Прочитано 804 раз)
demaker
Птица говорун
*****
Offline Offline

Сообщений: 928


Просмотр профиля
« : Декабрь 13, 2019, 17:15 »

Пытаюсь  реализовать обмен между процессами с помощью сокетов(AF_UNIX).
При тестировании через некоторое количество времени на стороне сервера происходит падение.
В syslog выводится сообщение:

Код
C++ (Qt)
Process 8949 (qt_daemon) of user 1000 dumped core.#012#012Stack trace of thread
8950:#12#0 0x00007f13eabde905 __GI__IO_link_in (lib.so.6)#012#1 0x00007f13eabdd132
_IO_new_fileinit internal (lib.so.6)#012#2 0x00007f13eabcf653 _IO_new_fdopen (lib.so.6)
#012#3   0x00007f13eabcc2f9 __GI_perror  (lib.so.6)#012#4 0x00005ebe88bf1ab n/a
(path to ELF)#012#6 0x0004000300000000 n/a (n/a)
 

Не могу понять из-за происходит падение на стороне сервера.
Вроде с сокета вычитываю все норм.
Подскажите в каком направлении искать ошибку

Код Сервера и Клиента привел ниже:

Код:
Код Клиента

Код
C++ (Qt)
include "thr_client_daemon.h"
 
//auto connect_ = connect;
 
#include <QDebug>
ThrClientDaemon::ThrClientDaemon(QObject * parent)
   :   QThread(parent)
{
   flag_state = active;
}
 
ThrClientDaemon::~ThrClientDaemon()
{
}
 
void ThrClientDaemon::run()
{
   struct timeval tv;
 
   struct sockaddr_un address;
   address.sun_family = AF_UNIX;
   char str_servaddr[] = "/home/user/server_socket";
 
   strcpy(address.sun_path, str_servaddr);
 
   uint len = sizeof (struct sockaddr_un);
   int sockfd = 0;
   int res_connect = -1;
   int cnt_attempt_err = 0;
 
   ssize_t res_wr = 0;
 
   while(get_flag_state()){
 
       sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
       res_connect = ::connect(sockfd, reinterpret_cast<const struct sockaddr *>(&address), len);
 
       emit oops_client("TRY TO CONNECT...");
 
       if(res_connect != -1){
 
           emit oops_client("Connection Success");
 
           SendMsg304T msg[3];
           {
               memset(&msg, 0, sizeof (SendMsg304T));
               msg[0].data.fpga_trg->frame_xy[0] = 1;
               msg[0].data.fpga_trg->frame_xy[1] = 2;
               msg[1].data.fpga_trg->frame_xy[0] = 3;
               msg[1].data.fpga_trg->frame_xy[1] = 4;
               msg[2].data.fpga_trg->frame_xy[0] = 5;
               msg[2].data.fpga_trg->frame_xy[1] = 6;
           }
 
           while (get_flag_state()) {
 
               tv.tv_sec = 0;
               tv.tv_usec =  1000;
               select(0, nullptr, nullptr, nullptr, &tv);
 
               if((res_wr = write_all(sockfd, reinterpret_cast<char*>(msg), 3 * sizeof (SendMsg304T))) > 0){
 
               }
               else{
                   qDebug() << "write_err: !ERR! " << res_wr;
 
                   if(cnt_attempt_err == 3){
 
                       emit oops_client("LET TRY TO CONNECT");
                       cnt_attempt_err = 0;
                       close(sockfd);
                       break;
 
                   }
                   else{
                       cnt_attempt_err++;
                       emit oops_client(QString("Client error[was attempts]: %1").arg(cnt_attempt_err));
                   }
               }
 
           }//while
       }
       else{
 
           emit oops_client("LET TRY TO CONNECT");
           close(sockfd);
 
           tv.tv_sec = 0;
           tv.tv_usec =  1 * 1000000;
           select(0, nullptr, nullptr, nullptr, &tv);
       }
 
   }//while
 
   close(sockfd);
   emit fin();
}
 

Код:
Код сервера

Код
C++ (Qt)
#include "server_socket.h"
 
long bytes_available(int sockfd)
{
   long int avail = 0;
   size_t bytes = 0;
 
   if(ioctl(sockfd, FIONREAD, reinterpret_cast<char*>(&bytes)) >= 0)
       avail = static_cast<long int>(*reinterpret_cast<size_t*>(&bytes));
 
   return avail;
}
 
ssize_t read_all(int sockfd, char *buf, size_t len)
{
   size_t length = len;
   ssize_t ret = 0;
   ssize_t res = 0;
 
   while (length != 0 && (ret = read(sockfd, buf, length)) != 0){
       if(ret == -1){
           perror("read");
           return 0;
       }
       length -= static_cast<size_t>(ret);
       buf += ret;
       res += ret;
   }
   return res;
}
 
int create_server_socket()
{
   int server_sockfd, server_len;
   struct sockaddr_un server_address;
   unlink("/home/user/server_socket");
 
   server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
   server_address.sun_family = AF_UNIX;
   strcpy(server_address.sun_path,"/home/user/server_socket");
   server_len = sizeof(server_address);
 
   fcntl(server_sockfd, F_SETFL, O_NONBLOCK); //set non block socket
   bind(server_sockfd, reinterpret_cast<struct sockaddr*>(&server_address), static_cast<socklen_t>(server_len));
   listen(server_sockfd, 5);
 
   return server_sockfd;
}
 
int wait_client_connection(int *server_sockfd, int waittime)
{    
   int client_sockfd, client_len;    
   struct sockaddr_un client_address;
 
   client_sockfd = client_len = 0;
 
   int epfd;
   epfd = epoll_create1(0);
   if(epfd < 0)    return -1;
 
   struct epoll_event event1;
   event1.data.fd = *server_sockfd;
   event1.events = EPOLLIN | EPOLLET;
 
   if(epoll_ctl(epfd, EPOLL_CTL_ADD, *server_sockfd, &event1))  return -1;
 
 
   struct epoll_event event[64];
   int nr_events = 0; //int ret = 0;
   do{
 
#ifdef DEBUG_TEXT_SYSLOG        
       printf("waiting connection during 1 sec\n");
#endif    
 
       nr_events = epoll_wait(epfd, event, 64, waittime); //ret = poll(&fds_server, 1, waittime); //1*1000
 
       if(nr_events < 0){
 
           return -1;
       }
 
       if(nr_events > 0){  
 
           int i = 0;
           for(i = 0; i < nr_events; i++){
 
               if(event[i].events & EPOLLIN){
 
                   client_len = sizeof(struct sockaddr_un);                    
                   client_sockfd = ::accept(*server_sockfd,
                                            reinterpret_cast<struct sockaddr*>(&client_address),
                                            reinterpret_cast<socklen_t*>(&client_len)
                                            );
 
                   fcntl(client_sockfd, F_SETFL, O_NONBLOCK); //set non block socket    
                   printf("accept");
               }
 
           }
 
           return client_sockfd;
 
       }
   }
   while(1);
 
}
 
void* server_working(void * arg)
{  
   struct arg_serv *a_serv;
   a_serv = reinterpret_cast<struct arg_serv *>(arg);
   int client_sockfd = a_serv->client_sockfd;
 
   int epfd;
   epfd = epoll_create1(0);
   if(epfd < 0)    return reinterpret_cast<void*>(a_serv);
 
   struct epoll_event event1;
   event1.data.fd = client_sockfd;
   event1.events = EPOLLIN | EPOLLET | EPOLLHUP | EPOLLRDHUP;
 
   epoll_ctl(epfd, EPOLL_CTL_ADD, client_sockfd, &event1);
 
   SendMsg304T/*MSG_304_T*/ indata[MAX_ARRAY_MSG_304_T];
   memset(indata, 0, MAX_ARRAY_MSG_304_T * sizeof (SendMsg304T/*MSG_304_T*/));
 
   int cnt_attempt_err = 0;
   int cnt_attempt_wait = 0;        
 
   struct epoll_event event[64];
   while(1){
 
       int nr_events = epoll_wait(epfd, event, 64, -1); //10 millsecond
 
       if(nr_events > 0){
 
           int i = 0;
           for(i = 0; i < nr_events; i++){
 
               if(event[i].events & EPOLLIN){
 
                   //
                   //read available bytes in socket
                   long int avail = bytes_available(client_sockfd);
                   printf("avail bytes in socket = %ld\n", avail);
 
                   if(avail > 0){
 
                       //
                       //try read data
 
                       long int rd = 0;
                       if((rd = read_all(client_sockfd, reinterpret_cast<char*>(indata), static_cast<size_t>(avail))) > 0
 
                               /*(rd = recv(client_sockfd, reinterpret_cast<char*>(indata), static_cast<size_t>(avail),   MSG_WAITALL))> 0*/
                               /*read(client_sockfd, indata, СЃ) > 0*/){
 
                           printf("was red = %ld\n", rd);
                       }
                   }
                   else{
 
                       if(cnt_attempt_err == 3){
 
                           cnt_attempt_err = 0;
 
                           //escape of while(1)
                           pthread_mutex_lock(&a_serv->mutex);
                           a_serv->work = false;
                           pthread_mutex_unlock(&a_serv->mutex);
 
                           a_serv->err = -1;
                           close(client_sockfd);
 
                           return reinterpret_cast<void*>(a_serv);
                       }
                       else{
                           cnt_attempt_err++;
#ifdef DEBUG_TEXT_SYSLOG                                
                           openlog("Skelet demona",LOG_PID|LOG_CONS,LOG_DAEMON);
                           syslog(LOG_INFO,"avail = %ld\n", avail);
                           closelog();
#endif
                       }
                   }
 
                   //read available bytes in socket
                   //
               }
 
               if(event[i].events & EPOLLHUP){
 
#ifdef DEBUG_TEXT_SYSLOG                    
                   openlog("Skelet demona",LOG_PID|LOG_CONS,LOG_DAEMON);
                   syslog(LOG_INFO,"!!!POLLHUP EVENT!!!\n");
                   closelog();
#endif                      
 
                   pthread_mutex_lock(&a_serv->mutex);
                   a_serv->work = false;
                   pthread_mutex_unlock(&a_serv->mutex);
 
                   a_serv->err = -2;
                   close(client_sockfd);
 
                   return reinterpret_cast<void*>(a_serv);
               }
 
               if(event[i].events & EPOLLRDHUP){//else if(fds_client.revents & POLLHUP){
 
#ifdef DEBUG_TEXT_SYSLOG                    
                   openlog("Skelet demona",LOG_PID|LOG_CONS,LOG_DAEMON);
                   syslog(LOG_INFO,"!!!POLLRDHUP EVENT!!!\n");
                   closelog();
#endif                      
                   pthread_mutex_lock(&a_serv->mutex);
                   a_serv->work = false;
                   pthread_mutex_unlock(&a_serv->mutex);
 
                   a_serv->err = -3;
                   close(client_sockfd);
 
                   return reinterpret_cast<void*>(a_serv);
               }
 
               if(event[i].events & EPOLLERR){
 
#ifdef DEBUG_TEXT_SYSLOG                
                   openlog("Skelet demona",LOG_PID|LOG_CONS,LOG_DAEMON);
                   syslog(LOG_INFO,"!!!POLLERR EVENT!!!\n");
                   closelog();
#endif
                   pthread_mutex_lock(&a_serv->mutex);
                   a_serv->work = false;
                   pthread_mutex_unlock(&a_serv->mutex);
 
                   a_serv->err = -4;
                   close(client_sockfd);
 
                   return reinterpret_cast<void*>(a_serv);
               }
 
           }//end for
 
           //
           //
       }
       else if(nr_events == 0){//else if(ret == 0){
           printf("cnt_wait = %d",cnt_attempt_wait++);
       }
       else{
#ifdef DEBUG_TEXT_SYSLOG
           openlog("Skelet demona",LOG_PID|LOG_CONS,LOG_DAEMON);
           syslog(LOG_INFO,"nr_events = -1\n");
           closelog();
#endif
 
           pthread_mutex_lock(&a_serv->mutex);
           a_serv->work = false;
           pthread_mutex_unlock(&a_serv->mutex);
 
           a_serv->err = -5;
           close(client_sockfd);
 
           return reinterpret_cast<void*>(a_serv);
       }
 
   } //end while(1)
 
}
 
 

Код:
main
Код
C++ (Qt)
#include <QCoreApplication>
 
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ioctl.h>
 
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/select.h>
#include <pthread.h>
 
#include "server_socket.h"
#include "global_varible.h"
#include "mil1553.h"
 
int main(int argc, char *argv[])
{
   int server_sockfd, client_sockfd;
   server_sockfd = create_server_socket();
 
   pthread_t thread_serv;
 
   struct arg_serv a_serv;
   memset(&a_serv, 0, sizeof(struct arg_serv));
 
   if((client_sockfd = wait_client_connection(&server_sockfd, 1 * 1000)) == -1)  return 1;
 
   a_serv.client_sockfd = client_sockfd;
   a_serv.mutex = PTHREAD_MUTEX_INITIALIZER;
   a_serv.work = true;
 
   if(!pthread_create(&thread_serv, nullptr, server_working, reinterpret_cast<void*>(&a_serv))){
       printf("create server thread");
   }
   else{
      printf("thread server error");
       return 1;
   }
 
   bool arg = true;
   while(arg){
 
       struct timeval tv;
       tv.tv_sec = 0;
       tv.tv_usec = 1000;
       select(0, nullptr, nullptr, nullptr, &tv);
 
       pthread_mutex_lock(&a_serv.mutex);
       arg = a_serv.work;
       pthread_mutex_unlock(&a_serv.mutex);
   }
 
   printf("Exit");
 
   struct arg_serv ret_arg_serv;
   void * ptr_ret = reinterpret_cast<void*>(&ret_arg_serv);
   pthread_join(thread_serv, &ptr_ret);
}
 
« Последнее редактирование: Декабрь 13, 2019, 17:39 от demaker » Записан
qate
Супер
******
Offline Offline

Сообщений: 1041


Просмотр профиля
« Ответ #1 : Декабрь 14, 2019, 13:43 »

Пытаюсь  реализовать обмен между процессами с помощью сокетов(AF_UNIX).

хм, а чем tcp сокеты не устроили ?

Подскажите в каком направлении искать ошибку

так ведь корка есть !
её и анализировать нужно )


Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1017


Просмотр профиля
« Ответ #2 : Март 19, 2020, 15:27 »

QLocalSocket вам в помощь
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.212 секунд. Запросов: 22.