QT 에서 UDP Socket 분실 문제 (계속)

3067 단어 QT
Qt 에서 UDP 송 수신 기 를 작성 하 는 패 킷 문 제 를 설명 하 였 습 니 다.
보다.http://blog.csdn.net/rabbitjerry/article/details/72674458
마침내 철저히 해결 되 었 고 윈도 운영 체제 와 리 눅 스 운영 체제 에서 모두 검증 되 었 다.
1. 해결 방향
1. 프로그램 에서 QThread 클래스 를 이용 하여 UDP 패 키 지 를 받 을 새로운 스 레 드 를 엽 니 다.
2. 윈도 운영 체제 에서 윈도 에 포 장 된 소켓 을 사용 하고 리 눅 스에 서 리 눅 스 의 소켓 을 사용 하여 Qt 의 QSocket 을 지운다.
3. 새 스 레 드 에서 while 순환 을 사용 하고 Socket 기본 차단 모드 로 데 이 터 를 수신 합 니 다.
4. 여러 프로그램 을 유지 하 는 것 을 피하 기 위해 서 매크로 제 어 를 사용 하 는 것 이 윈도 우즈 의 소켓 인지 리 눅 스 의 소켓 인지 서로 다른 환경 에서 매크로 정 의 를 변경 한 후에 다시 컴 파일 하면 사용 과 유지 에 편리 합 니 다.
이로써 가방 을 잃 어 버 리 지 않 고 CPU 점용 율 도 낮다 (차단 모드 를 사 용 했 기 때문이다).
핵심 코드
1. 매크로 정의 와 헤더 파일 참조
#define _WIN_SOCKET_   1
#define _QT_SOCKET_    0
#define _LINUX_SOCKET_ 0

#if _WIN_SOCKET_   // for windows OS 
#include 
#include 
#endif

#if _LINUX_SOCKET_  // for Linux OS
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#endif

2. 헤더 파일 의 코드
#if _QT_SOCKET_
private:
    QUdpSocket * p_echo_socket;
#endif

#if _WIN_SOCKET_  // for windows OS
private:
    WSADATA wsaData;
    WORD sockVersion;
    SOCKET echo_socket_WIN;
    sockaddr_in addr_WIN;
    sockaddr_in src_addr_WIN;
    int src_addr_len = sizeof(src_addr_WIN);
#endif

#if _LINUX_SOCKET_
private:
    int socket_len;
    int socket_descriptor;
    struct sockaddr_in echo_socket_LINUX;
#endif

3. 구조 함수 에서 socket 과 관련 된 내용
    /************* socket **************/
#if _QT_SOCKET_   
    p_echo_socket = new QUdpSocket(this);
    p_echo_socket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, 4*1024*1024);//    
    if(!p_echo_socket->bind(DRY_ECHO_NET_PORT))  //     
    {
        qDebug()<

4. 수신 데이터 함수 중 socket 과 관련 된 코드
    while(1)
    {
        net_pack_size = 0;

#if _QT_SOCKET_
        if( p_echo_socket->hasPendingDatagrams())  //    
        {
            net_pack_size = p_echo_socket->pendingDatagramSize();
            p_echo_socket->readDatagram((char*)p_echo_net_pack,net_pack_size);
        }
#endif

#if _WIN_SOCKET_
        net_pack_size = recvfrom(echo_socket_WIN, (char*)p_echo_net_pack, 1600, 0, (sockaddr *)&src_addr_WIN, &src_addr_len);
#endif

#if _LINUX_SOCKET_
        net_pack_size = recvfrom(socket_descriptor,(char*)p_echo_net_pack,1600,0,(struct sockaddr *)&echo_socket_LINUX,(socklen_t*)&socket_len);
#endif
...


주의사항
1. pro 파일 은 Windows 운영 체제 에 다음 과 같은 라 이브 러 리 를 추가 해 야 하지만 Linux 시스템 에 서 는 이 줄 코드 를 주석 해 야 합 니 다.
LIBS+=-lpthreadlibwsock32libws2_32#forwindowsOS
2. Ubuntu 운영 체제 에서 캐 시 크기 의 상한 선 을 설정 하 는 것 은 운영 체제 의 한 파일 에 의 해 제 한 됩 니 다. 이 때 기본 수신 캐 시 최대 값 을 수 동 으로 수정 해 야 합 니 다: 열기 / proc / sys / net / core / rmemmax: 4194304 Ubuntu 16.0 으로 바 뀌 었 습 니 다. 기본 값 은 212992 입 니 다.
[20170601]

좋은 웹페이지 즐겨찾기