QTcpSocket사용 시 플러그 뽑힘 증상 체크 방법 > QT 강좌/팁

본문 바로가기
사이트 내 전체검색

QT 강좌/팁

QT/Embedded QTcpSocket사용 시 플러그 뽑힘 증상 체크 방법

페이지 정보

작성자 no_profile 요원009 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글 0건 조회 12,238회 작성일 15-11-13 10:40

본문



아래는 진행하면서 참고했던 사이트들입니다.









Unplugging ethernet




Qt에서 소켓을 사용하다보면 끊어진 경우를 확인해야할 상황이 발생합니다.


뭐... 굳이 Qt가 아니더라도 언제 어디서나 서비스 제공자는 무조건 확인해야 합니다만,


Qt를 이용한 프로그래밍을 할 땐, 단순히 플러그가 뽑힌 경우를 체크하기엔 조금 까다롭습니다.




왜냐면 QAbstractSocket 클래스가 제공하는 ConnectedState는


연결된 이후에 물리적인 플러그 뽑힘 현상에 대해선 확인해주질 못합니다.




슬프게도,


Qt가 제공하는 그 어떤 소켓 클래스들도 물리적인 플러그 Unconnected를 확인하질 못합니다.




그래서 조금 돌아가는 방법을 사용해야 합니다.






Simple Main Code




우선, 간단한 Socket Program을 만들어 봅니다.




main.h

1
2
3
4
5
6
7
8
9
10
11
#include <QProcess>
#include <QTcpSocket>

QProcess ping_process_;
QStringList ping_params_;

private slots:
    void HandleConnected();
    void HandleDisconnected();
    void HandleReadyRead();
    void HandleStateChange(QAbstractSocket::SocketState state);





main.cpp




1
2
3
4
5
6
7
8
9
10
11
     tcp_socket_ = new QTcpSocket(this);
    //tcp_socket_->setSocketOption(QAbstractSocket::KeepAliveOption, 1);

    connect(tcp_socket_, SIGNAL(connected()), this, SLOT(HandleConnected()));
    connect(tcp_socket_, SIGNAL(readyRead()), this, SLOT(HandleReadyRead()));
    connect(tcp_socket_, SIGNAL(disconnected()), this, SLOT(HandleDisconnected()));
    connect(tcp_socket_, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,
     SLOT(HandleStateChange(QAbstractSocket::SocketState)));


ping_params_ << "-c" << "1" << server_ip_;





아주 간단한 프로그램입니다.


4개의 slot은 연결, 끊김, 읽기, 상태 변화를 의미합니다.


메인 코드의 마지막엔 연결이 잘 이루어졌는지 ping을 날려보는 간단한 코드도 들어있습니다.






Ping and QProcess




Ping 테스트를 할 땐, http://를 넣으면 오류가 발생하고,


Window와 Linux에선 서로 다른 인자를 사용하니 그것도 확인해 줘야 합니다.


이를 확인하지 않으면 아래와 유사한 에러 메세지가 뜰겁니다.





error, message



  • Try removing "http://" in line number
  • Ping expects an IP or an hostname, "http://" isn't part of the hostname.
  • cout<<"\n\nexitCode,exitStatus=="<<exitCode<<","<<exitStatus





ping 코드를 작성할 아래처럼 http://를 제거하고 난 뒤에 시도하셔야 합니다.


그러면 아래와 같은 코드를 작성하실 수 있습니다. 아주 간단하게 말이죠.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#if defined(WIN32)
   QString parameter = "-n 1";
#else
   QString parameter = "-c 1";
#endif

int exitCode = QProcess::execute("ping", QStringList() << parameter << "1.1.1.11");
if (exitCode==0) 
{
    // it's alive
} else 
{
    // it's dead
}

.....
params << "-c" << "1" << "www.google.com";





ConnectToServer function




1
2
3
4
5
6
7
void TcpClient::ConnectToServer()
{
    if (tcp_socket_->state() != QAbstractSocket::ConnectedState &&
            tcp_socket_->state() != QAbstractSocket::ConnectingState) {
        tcp_socket_->connectToHost(server_ip_, server_port_);
    }
}





위에서 선언만 했던 ConnecToServer 함수를 정의합니다.


socket 객체가 아직도 연결되지 않은 상태라면 연결을 시도합니다.


이것도 아주 간단하죠?






HandleConnected function




1
2
3
4
5
6
7
8
void TcpClient::HandleConnected()
{
    qWarning() << "connect Complete";

    bla~ bla~ bla~

    emit ConnectionComplete();
}
 


이어서 HandleConnected 함수도 정의합니다.

이름 그대로 연결이 되면 구동되는 함수입니다.


내부의 코드는 각자 입맛에 맞춰 구성하면 됩니다.






StateChange property




StateChange 속성은 아래와 같습니다.






Constant

Value

Description

 QAbstractSocket::UnconnectedState

 0

 The socket is not connected.

 QAbstractSocket::HostLookupState

 1

 The socket is performing a host name lookup.

 QAbstractSocket::ConnectingState

 2

 The socket has started establishing a connection.

 QAbstractSocket::ConnectedState

 3

 A connection is established.

 QAbstractSocket::BoundState

 4

 The socket is bound to an address and port (for servers).

 QAbstractSocket::ClosingState

 6

 The socket is about to close (data may still be waiting to be written).

 QAbstractSocket::ListeningState

 5

 For internal use only.






일반적으로 주로 사용하는 Constant는 굵게 표시된 위의 두 개입니다.


아무튼, 저 표를 통해서 유추할 수 있는 아주 간단한 사실은,




1
2
3
4
5
// Normal
QAbstractSocket::ConnectedState

// Abnormal
QAbstractSocket::UnconnectedState





이겁니다.


그래서 아래와 같은 한 줄로 코드에서 분기가 가능합니다.




1
tcp_socket_->state() == QAbstractSocket::UnconnectedState





아래엔 실제 구현할 수 있는 소켓 프로그램의 전체 코드입니다.


(위와 이어지는 내용)




1
2
3
4
5
6
7
void TcpClient::HandleStateChange(QAbstractSocket::SocketState state)
{
    if (tcp_socket_->state() == QAbstractSocket::UnconnectedState)
        HandleDisconnected();

    qWarning() << "State Changed : " << state;
}




1
2
3
4
5
6
7
8
9
10
11
void TcpClient::HandleDisconnected()
{
    if (timer_connecte_->isActive() == false) {
        tcp_socket_->close();
   bla~ bla~
    }

    emit ConnectionError();

    qWarning() << "HandleDisconnected";
}





1
2
3
4
5
void TcpClient::HandleReadyRead()
{
    recv_data_ = tcp_socket_->readAll();
    CheckPacketID();
}





자, 이제 몇 가지 케이스를 들어 Qt의 소켓이 여러 끊김 현상을 감지할 수 있는지 확인합니다.


물론 위에 나온 코드를 이용해 테스트를 진행할 겁니다.


(위의 코드만 복사하면 프로그램 하나가 만들어지니깐요)






Case1 : Unplugged ethernet



QProcess에서 과연 ethernet의 끊김을 확인할 수 있을까?
output 메시지와 error 메시지를 확인하면 알 수 있습니다.


output message

정상적인 상황 : 아래 메시지

"PING 192.168.1.17 (192.168.1.17) 56(84) bytes of data.
64 bytes from 192.168.1.17: icmp seq=1 ttl=128 time=0.830ms

--- 192.168.1.17 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.830/0.830/0.830/0.000 ms"


비정상적인 상황 : 없음


error message

정상적인 상황 : 없음

비정상적인 상황 : 아래 메시지

connect: Network is unreachable


분명히 error 메시지를 통해서 이더넷의 연결 끊김은 확실히 확인 할 수 있습니다.


Case2 : Power off the target (thing..)

어떤게 연결된진 모르겠지만, 하여간에 연결된 장치쪽의 전원이 꺼진 상태입니다.
PLC가 될 수도 있고, 작은 임베디드 보드일 수도 있고, 데스크탑일 수도 있고, 경우는 많습니다.


output message

정상적인 상황 : 아래 메시지

"PING 192.168.1.17 (192.168.1.17) 56(84) bytes of data.
64 bytes from 192.168.1.17: icmp seq=1 ttl=128 time=0.830ms

--- 192.168.1.17 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.830/0.830/0.830/0.000 ms"


비정상적인 상황 : 없음


error message

정상적인 상황 : 아래 메시지

QProcess: Destroyed while process ("ping") is still running.


비정상적인 상황 : 없음


ping을 통해서 연결 끊김이 확인됩니다.
Case1에선 ethernet이 끊어짐을 확인했으나 이번엔 그러질 못했습니다.
오직 ping 메시지를 통해서만 알 수 있습니다.


Solution

단순히 StateChange 속성만 가지고선 (안타깝게도)언플러그를 확인할 수가 없습니다.
그래서 Case2와 같이 ping을 전달하는 방법으로 언플러그를 확인해야 합니다.
Ping을 다루는 소스는 위의 소스처럼 아주 간단합니다(정말 간단해서 계속 간단하다고...).

1
2
3
4
5
6
QProcess p;
p.start( /* whatever your command is, see the doc for param types */ );
p.waitForFinished(-1);

QString p_stdout = p.readAllStandardOutput();
QString p_stderr = p.readAllStandardError();



원형은 위와 같은데 실제 응용하기 위해선 뭔가 변화를 줘야 합니다.
저는 아래처럼 소스를 구성해 메인 클래스에 추가했습니다.

1
2
3
4
5
6
7
8
9
   

개인 블로그 http://yowon009.tistory.com/

추천0

댓글목록

등록된 댓글이 없습니다.

Total -1,121건 1 페이지
QT 강좌/팁 목록
번호 제목 글쓴이 조회 추천 날짜
-1121 QT/Win32 no_profile 주영대감 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 697 0 05-31
-1122 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5488 0 09-10
-1123 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6742 0 12-03
-1124 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7791 1 03-07
열람중 QT/Embedded no_profile 요원009 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 12239 0 11-13
-1126 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7246 0 05-18
-1127 QT/Embedded no_profile 잉농 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6949 0 05-14
-1128 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7434 0 04-01
-1129 QT/Embedded no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 24463 1 03-31
-1130 QT/Win32 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 15433 0 03-17
-1131 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6518 0 02-13
-1132 QT/Win32 no_profile 인라이너 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6501 1 02-12
-1133 QT/Embedded no_profile 김아무개 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 18093 0 11-12
-1134 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6423 0 11-11
-1135 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6461 0 11-11
-1136 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11835 0 10-22
-1137 QT/Win32
Qt와 C++11 댓글+ 2
no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 12061 1 10-12
-1138 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 12687 0 10-09
-1139 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8477 0 10-02
-1140 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10254 0 10-01
-1141 QT/X11 no_profile 별님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5929 0 09-25
-1142 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6943 0 09-16
-1143 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8144 0 09-03
-1144 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8024 0 09-02
-1145 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8523 2 09-02
-1146 QT/X11 no_profile 나무나무나무 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9486 0 07-25
-1147 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7458 2 07-11
-1148 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10553 2 07-09
-1149 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7279 2 07-08
-1150 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 14575 1 07-07
게시물 검색

  • 게시물이 없습니다.

회원로그인

설문조사

새로운 홈페이지에 대한 평가

접속자집계

오늘
771
어제
1,129
최대
3,878
전체
4,332,021

Copyright © korone.net. All rights reserved.