[Windows의 UltraVNC와 Linux의 TigerVNC 간의 파일 전송 - rfbFileTransferMsg 구조 보내기 및 받기]

rfbFileTransferMsg 구조 정의

UltraVNC의 구조 정의, 총 12바이트

typedef struct _rfbFileTransferMsg {
    
    
    CARD8 type;			/* always rfbFileTransfer */
    CARD8 contentType;  // See defines below
    CARD16 contentParam;// Other possible content classification (Dir or File name, etc..)
	CARD32 size;		// FileSize or packet index or error or other 
	// CARD32 sizeH;		// Additional 32Bits params to handle big values. Only for V2 (we want backward compatibility between all V1 versions)
    CARD32 length;
    /* followed by data char text[length] */
} rfbFileTransferMsg;

TigerVNC에는 그러한 구조가 없으므로 다음과 같이 직접 정의해야 하며, 이 역시 총 12바이트입니다.

typedef struct _rfbFileTransferMsg {
    
    
    rdr::U8 type;			/* always rfbFileTransfer */
    rdr::U8 contentType;  // See defines below
    rdr::U16 contentParam;// Other possible content classification (Dir or File name, etc..)
	rdr::U32 size;		// FileSize or packet index or error or other 
	// rdr::U32 sizeH;		// Additional 32Bits params to handle big values. Only for V2 (we want backward compatibility between all V1 versions)
    rdr::U32 length;
    /* followed by data char text[length] */
} rfbFileTransferMsg;

Windows의 UltraVNC는 Linux의 TigerVNC에 구조를 보냅니다.

1. Windows를 통해 보냅니다. 예를 들어:

if (m_client->fFTRequest)
{
    
    
	rfbFileTransferMsg ft;
	ft.type = rfbFileTransfer;
	ft.contentType = rfbAbortFileTransfer;

	bool bOldFTProtocole = (msg.ft.contentParam == 0);
	if (bOldFTProtocole)
		ft.contentType = rfbAbortFileTransfer; // Viewer with New V2 FT protocole
	else
		ft.contentType = rfbFileTransferAccess; // Viewer with old FT protocole

	if (!bOldFTProtocole && m_server->FileTransferEnabled() && m_client->m_server->RemoteInputsEnabled() && fUserOk)
		ft.size = Swap32IfLE(1);
	else
		ft.size = Swap32IfLE(-1); 
	m_client->m_socket->SendExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
	m_client->fFTRequest = false;
}

2. Linux 수신은
Windows와 같이 다음과 같은 방법으로는 수신할 수 없습니다. 수신된 구조의 각 필드에 바이트 순서 문제가 있기 때문입니다.

rfbFileTransferMsg ft;
is->readBytes(((char *)&ft), sz_rfbFileTransferMsg);

여기서는 TigerVNC에서 제공하는 readU8(), readU16(), readU32()를 사용하여 아래와 같이 순서대로 12바이트를 읽고 읽습니다.

  int type = is->readU8();
  int c_contentType = is->readU8();
  int c_contentParam = is->readU8();
  int c_contentParam_sub = is->readU8();
  int c_size = is->readU32();
  int c_length = is->readU32();

Linux의 TigerVNC는 Windows의 UltraVNC에 구조를 보냅니다.

1. Linux 측에서 보내기
바이트 순서 문제로 인해 Windows와 같이 다음과 같은 방법으로는 보낼 수 없습니다.

rfbFileTransferMsg ft;
ft.type = msgTypeFileTransfer;
ft.contentType = rfbDirContentRequest;
ft.contentParam = rfbRDrivesList; // List of Remote Drives please
ft.length = 0;

char *char_ft = (char *)&ft;
os->writeBytes(char_ft, sz_rfbFileTransferMsg);

여기서는 TigerVNC에서 제공하는 writeU8(), writeU16(), writeU32()를 사용하여 아래와 같이 12바이트를 순서대로 전송합니다.

os->writeU8(7);
os->writeU8(1);
os->writeU8(1);
os->writeU8(0);
os->writeU32(0);
os->writeU32(1022);

2. Windows 측에서 읽기,
먼저 1바이트 읽기

rfbClientToServerMsg msg;
if (!m_socket->ReadExact((char *)&msg.type, sizeof(msg.type)))
{
    
    
	m_client->cl_connected = FALSE;
	break;
}

또 다른 11바이트 읽기

if (m_socket->ReadExact(((char *) &msg) + 1, sz_rfbFileTransferMsg - 1))
{
    
    
}

rfbClientToServerMsg 구조는 rfbFileTransferMsg를 포함하여 다음과 같습니다.

typedef union {
    
    
    CARD8 type;
    rfbSetPixelFormatMsg spf;
    rfbFixColourMapEntriesMsg fcme;
    rfbSetEncodingsMsg se;
    rfbFramebufferUpdateRequestMsg fur;
    rfbKeyEventMsg ke;
    rfbPointerEventMsg pe;
    rfbClientCutTextMsg cct;
	rfbSetScaleMsg ssc;
	rfbPalmVNCSetScaleFactorMsg pssf;
	rfbSetServerInputMsg sim;
	rfbFileTransferMsg ft;
	rfbSetSWMsg sw;
	rfbTextChatMsg tc;
    rfbKeepAliveMsg kp;
	rfbRequestSessionMsg rs;
	rfbSetSessionMsg ss;
	rfbUserCloseMsg	close;
} rfbClientToServerMsg;

추천

출처blog.csdn.net/qq_33594636/article/details/131522685