VC FTP 서버 프로그램 분석(4)
1. OnAccept 데이터 tcp 서버가 연결된 허함수로 프레임워크에서 호출됩니다.
1 void CDataSocket::OnAccept(int nErrorCode)
2 {
3 // Accept the connection using a temp CSocket object.
4 CAsyncSocket tmpSocket;
5 Accept(tmpSocket);
6
7 SOCKET socket = tmpSocket.Detach();
8 Close();
9
10 Attach(socket);
11
12 m_bConnected = TRUE;
13
14 CAsyncSocket::OnAccept(nErrorCode);
15 }
일곱 번째 줄은 플러그인 설명자 socket을 얻을 수 있습니다.8줄은 감청된 이 플러그인을 닫고, 11줄은 socket과 본 대상, 12줄, 연결 표지를 표시합니다.이런 처리 방법은 한 종류를 적게 쓴다.tcp가 socket을 감청하기 때문에, 연결된 클라이언트도 socket을 사용하여 통신해야 합니다.이렇게 하면 클라이언트가 하나밖에 없는 상황에 적합하다.
2. OnReceive 데이터 수신 처리 함수
1 int CDataSocket::Receive()
2 {
3 TRACE("OnReceive
");
4 int nRead = 0;
5
6 if (m_pControlSocket->m_nStatus == STATUS_UPLOAD)
7 {
8 if (m_File.m_hFile == NULL)
9 return 0;
10
11 byte data[PACKET_SIZE];
12 nRead = CAsyncSocket::Receive(data, PACKET_SIZE);
13
14 switch(nRead)
15 {
16 case 0:
17 {
18 m_File.Close();
19 m_File.m_hFile = NULL;
20 Close();
21 // tell the client the transfer is complete.
22 m_pControlSocket->SendResponse("226 Transfer complete");
23 // destroy this socket
24 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);
25 break;
26 }
27 case SOCKET_ERROR:
28 {
29 if (GetLastError() != WSAEWOULDBLOCK)
30 {
31 m_File.Close();
32 m_File.m_hFile = NULL;
33 Close();
34 m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");
35 // destroy this socket
36 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);
37 }
38 break;
39 }
40 default:
41 {
42 TRY
43 {
44 m_File.Write(data, nRead);
45 }
46 CATCH_ALL(e)
47 {
48 m_File.Close();
49 m_File.m_hFile = NULL;
50 Close();
51 m_pControlSocket->SendResponse("450 Can't access file.");
52 // destroy this socket
53 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);
54 return 0;
55 }
56 END_CATCH_ALL;
57 break;
58 }
59 }
60 }
61 return nRead;
62 }
업로드 상태이면 수신한 데이터를 파일에 기록합니다.
3. PreSendFile 파일 전송과 관련된 함수
1 BOOL CDataSocket::PrepareSendFile(LPCTSTR lpszFilename)
2 {
3 // close file if it's already open
4 if (m_File.m_hFile != NULL)
5 {
6 m_File.Close();
7 }
8
9 // open source file
10 if (!m_File.Open(lpszFilename, CFile::modeRead | CFile::typeBinary))
11 {
12 return FALSE;
13 }
14 m_nTotalBytesSend = m_File.GetLength();
15
16 if (m_pControlSocket->m_dwRestartOffset < m_nTotalBytesSend)
17 {
18 m_nTotalBytesTransfered = m_pControlSocket->m_dwRestartOffset;
19 }
20 else
21 {
22 m_nTotalBytesTransfered = 0;
23 }
24 return TRUE;
25 }
초기화 파일 설명자 m_File,m_nTotalBytesSend,m_nTotalBytesTransfered.
4. SendFile 함수는 PrepareSendFile을 호출하고 OnSend를 호출하여 파일을 보냅니다.
1 void CDataSocket::SendFile(LPCTSTR lpszFilename)
2 {
3 if (!PrepareSendFile(lpszFilename))
4 {
5 // change status
6 m_pControlSocket->m_nStatus = STATUS_IDLE;
7
8 m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");
9
10 // destroy this socket
11 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);
12 return;
13 }
14 OnSend(0);
15 }
5. 전송 데이터는 LIST 명령을 위해 준비된 것으로 파일 디렉터리 목록을 보냅니다.
6. OnSend는 주로 list 명령의 상황과 다운로드의 상황을 구분한다.
1 void CDataSocket::OnSend(int nErrorCode)
2 {
3 CAsyncSocket::OnSend(nErrorCode);
4 switch(m_pControlSocket->m_nStatus)
5 {
6 case STATUS_LIST:
7 {
8 while (m_nTotalBytesTransfered < m_nTotalBytesSend)
9 {
10 DWORD dwRead;
11 int dwBytes;
12
13 CString strDataBlock;
14
15 dwRead = m_strData.GetLength();
16
17 if (dwRead <= PACKET_SIZE)
18 {
19 strDataBlock = m_strData;
20 }
21 else
22 {
23 strDataBlock = m_strData.Left(PACKET_SIZE);
24 dwRead = strDataBlock.GetLength();
25 }
26
27 if ((dwBytes = Send(strDataBlock, dwRead)) == SOCKET_ERROR)
28 {
29 if (GetLastError() == WSAEWOULDBLOCK)
30 {
31 Sleep(0);
32 return;
33 }
34 else
35 {
36 TCHAR szError[256];
37 wsprintf(szError, "Server Socket failed to send: %d", GetLastError());
38
39 // close the data connection.
40 Close();
41
42 m_nTotalBytesSend = 0;
43 m_nTotalBytesTransfered = 0;
44
45 // change status
46 m_pControlSocket->m_nStatus = STATUS_IDLE;
47
48 m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");
49
50 // destroy this socket
51 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);
52 }
53 }
54 else
55 {
56 m_nTotalBytesTransfered += dwBytes;
57 m_strData = m_strData.Mid(dwBytes);
58 }
59 }
60 if (m_nTotalBytesTransfered == m_nTotalBytesSend)
61 {
62 // close the data connection.
63 Close();
64
65 m_nTotalBytesSend = 0;
66 m_nTotalBytesTransfered = 0;
67
68 // change status
69 m_pControlSocket->m_nStatus = STATUS_IDLE;
70
71 // tell the client the transfer is complete.
72 m_pControlSocket->SendResponse("226 Transfer complete");
73 // destroy this socket
74 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);
75 }
76 break;
77 }
78 case STATUS_DOWNLOAD:
79 {
80 while (m_nTotalBytesTransfered < m_nTotalBytesSend)
81 {
82 // allocate space to store data
83 byte data[PACKET_SIZE];
84
85 m_File.Seek(m_nTotalBytesTransfered, CFile::begin);
86
87 DWORD dwRead = m_File.Read(data, PACKET_SIZE);
88
89 int dwBytes;
90
91 if ((dwBytes = Send(data, dwRead)) == SOCKET_ERROR)
92 {
93 if (GetLastError() == WSAEWOULDBLOCK)
94 {
95 Sleep(0);
96 break;
97 }
98 else
99 {
100 TCHAR szError[256];
101 wsprintf(szError, "Server Socket failed to send: %d", GetLastError());
102
103 // close file.
104 m_File.Close();
105 m_File.m_hFile = NULL;
106
107 // close the data connection.
108 Close();
109
110 m_nTotalBytesSend = 0;
111 m_nTotalBytesTransfered = 0;
112
113 // change status
114 m_pControlSocket->m_nStatus = STATUS_IDLE;
115
116 m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");
117
118 // destroy this socket
119 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);
120 }
121 }
122 else
123 {
124 m_nTotalBytesTransfered += dwBytes;
125 }
126 }
127 if (m_nTotalBytesTransfered == m_nTotalBytesSend)
128 {
129 // close file.
130 m_File.Close();
131 m_File.m_hFile = NULL;
132
133 // close the data connection.
134 Close();
135
136 m_nTotalBytesSend = 0;
137 m_nTotalBytesTransfered = 0;
138
139 // change status
140 m_pControlSocket->m_nStatus = STATUS_IDLE;
141
142 // tell the client the transfer is complete.
143 m_pControlSocket->SendResponse("226 Transfer complete");
144 // destroy this socket
145 AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, 0, 0);
146 }
147 break;
148 }
149 }
150 }
7. OnConnect 함수 tcp 연결이 성공했을 때 프레임워크에 호출된 허함수입니다.
8. OnClose 함수는 데이터 전송이 완료되거나 수신이 완료되면 프레임워크에 호출된 허함수입니다.주로 청소를 하다.
9、
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.