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

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

QT 강좌/팁

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

페이지 정보

작성자 no_profile 요원009 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글 0건 조회 11,708회 작성일 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 37건 1 페이지
QT 강좌/팁 목록
번호 제목 글쓴이 조회 추천 날짜
37 QT/Win32 no_profile 주영대감 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 189 0 05-31
36 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 4754 0 09-10
35 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6159 0 12-03
34 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7323 1 03-07
열람중 QT/Embedded no_profile 요원009 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11709 0 11-13
32 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6846 0 05-18
31 QT/Embedded no_profile 잉농 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6572 0 05-14
30 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7037 0 04-01
29 QT/Embedded no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 23290 1 03-31
28 QT/Win32 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 14407 0 03-17
27 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6168 0 02-13
26 QT/Win32 no_profile 인라이너 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6116 1 02-12
25 QT/Embedded no_profile 김아무개 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 17170 0 11-12
24 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6113 0 11-11
23 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6140 0 11-11
22 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11207 0 10-22
21 QT/Win32
Qt와 C++11 댓글+ 2
no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11467 1 10-12
20 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11536 0 10-09
19 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8018 0 10-02
18 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9434 0 10-01
17 QT/X11 no_profile 별님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5645 0 09-25
16 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6506 0 09-16
15 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7851 0 09-03
14 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7732 0 09-02
13 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8226 2 09-02
12 QT/X11 no_profile 나무나무나무 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8918 0 07-25
11 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7100 2 07-11
10 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10019 2 07-09
9 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6929 2 07-08
8 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 13823 1 07-07
게시물 검색

  • 게시물이 없습니다.

회원로그인

설문조사

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

접속자집계

오늘
750
어제
1,141
최대
3,878
전체
4,198,500

Copyright © korone.net. All rights reserved.