Пытаюсь реализовать обмен между процессами с помощью сокетов(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)
}
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);
}