Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #define _WINSOCK_DEPRECATED_NO_WARNINGS
- #include "Winsock2.h" // necessary for sockets, Windows.h is not needed.
- #include "mswsock.h"
- #include "process.h" // necessary for threading
- //
- // Global variables
- //
- TCHAR CommandBuf[81];
- HANDLE hCommandGot; // event "the user has typed a command"
- HANDLE hStopCommandGot; // event "the main thread has recognized that it was the stop command"
- HANDLE hCommandProcessed; // event "the main thread has finished the processing of command"
- HANDLE hConnectCommandGot;
- HANDLE hSendPassword;
- HANDLE hReadKeyboard; // keyboard reading thread handle
- HANDLE hStdIn; // stdin standard input stream handle
- WSADATA WsaData; // filled during Winsock initialization
- DWORD Error;
- SOCKET hClientSocket = INVALID_SOCKET;
- sockaddr_in ClientSocketInfo;
- HANDLE hReceiveNet; // TCP/IP info reading thread handle
- HANDLE hSendNet;
- BOOL SocketError;
- //
- // Prototypes
- //
- unsigned int __stdcall ReadKeyboard(void* pArguments);
- unsigned int __stdcall ReceiveNet(void* pArguments);
- unsigned int __stdcall SendNet(void* pArguments);
- //****************************************************************************************************************
- // MAIN THREAD
- //****************************************************************************************************************
- int _tmain(int argc, _TCHAR* argv[])
- {
- //
- // Initializations for multithreading
- //
- if (!(hCommandGot = CreateEvent(NULL, TRUE, FALSE, NULL)) ||
- !(hStopCommandGot = CreateEvent(NULL, TRUE, FALSE, NULL)) ||
- !(hCommandProcessed = CreateEvent(NULL, TRUE, TRUE, NULL)) ||
- !(hConnectCommandGot = CreateEvent(NULL, TRUE, FALSE, NULL)) )
- {
- _tprintf(_T("CreateEvent() failed, error %d\n"), GetLastError());
- return 1;
- }
- //
- // Prepare keyboard, start the thread
- //
- hStdIn = GetStdHandle(STD_INPUT_HANDLE);
- if (hStdIn == INVALID_HANDLE_VALUE)
- {
- _tprintf(_T("GetStdHandle() failed, error %d\n"), GetLastError());
- return 1;
- }
- if (!SetConsoleMode(hStdIn, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT))
- {
- _tprintf(_T("SetConsoleMode() failed, error %d\n"), GetLastError());
- return 1;
- }
- if (!(hReadKeyboard = (HANDLE)_beginthreadex(NULL, 0, &ReadKeyboard, NULL, 0, NULL)))
- {
- _tprintf(_T("Unable to create keyboard thread\n"));
- return 1;
- }
- //
- // Initializations for socket
- //
- if (Error = WSAStartup(MAKEWORD(2, 0), &WsaData)) // Initialize Windows socket support
- {
- _tprintf(_T("WSAStartup() failed, error %d\n"), Error);
- SocketError = TRUE;
- }
- else if ((hClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
- {
- _tprintf(_T("socket() failed, error %d\n"), WSAGetLastError());
- SocketError = TRUE;
- }
- //
- // Connect client to server
- //
- if (!SocketError)
- {
- ClientSocketInfo.sin_family = AF_INET;
- ClientSocketInfo.sin_addr.s_addr = inet_addr("127.0.0.1");
- ClientSocketInfo.sin_port = htons(1234); // port number is selected just for example
- if (connect(hClientSocket, (SOCKADDR*)&ClientSocketInfo, sizeof(ClientSocketInfo)) == SOCKET_ERROR)
- {
- _tprintf(_T("Unable to connect to server, error %d\n"), WSAGetLastError());
- SocketError = TRUE;
- }
- }
- //
- // Start net receiving thread
- //
- if (!SocketError)
- {
- if (!(hReceiveNet = (HANDLE)_beginthreadex(NULL, 0, &ReceiveNet, NULL, 0, NULL)))
- {
- _tprintf(_T("Unable to create socket receiving thread\n"));
- goto out;
- }
- if (!(hSendNet = (HANDLE)_beginthreadex(NULL, 0, &SendNet, NULL, 0, NULL)))
- {
- _tprintf(_T("Unable to create socket receiving thread\n"));
- goto out;
- }
- }
- //start net sending thread
- //
- // Main processing loop
- //
- while (TRUE)
- {
- if (WaitForSingleObject(hCommandGot, INFINITE) != WAIT_OBJECT_0)
- { // Wait until the command has arrived (i.e. until CommandGot is signaled)
- _tprintf(_T("WaitForSingleObject() failed, error %d\n"), GetLastError());
- goto out;
- }
- ResetEvent(hCommandGot); // CommandGot back to unsignaled
- if (!_tcsicmp(CommandBuf, _T("exit"))) // Case-insensitive comparation
- {
- SetEvent(hStopCommandGot); // To force the other threads to quit
- break;
- }
- else if (!_tcsicmp(CommandBuf, _T("connect"))) // tuleb connectimine
- {
- _tprintf("Command connect accepted, nothing to do yet\n");
- SetEvent(hConnectCommandGot); //event, et connect käsk anti käiku
- SetEvent(hCommandProcessed); //event, et käsu täitmine on lõppenud
- }
- else
- {
- _tprintf(_T("Command \"%s\" not recognized\n"), CommandBuf);
- SetEvent(hCommandProcessed); // To allow the keyboard reading thread to continue
- }
- }
- //
- // Shut down
- //
- out:
- if (hReadKeyboard)
- {
- WaitForSingleObject(hReadKeyboard, INFINITE); // Wait until the end of keyboard thread
- CloseHandle(hReadKeyboard);
- }
- if (hReceiveNet)
- {
- WaitForSingleObject(hReceiveNet, INFINITE); // Wait until the end of receive thread
- CloseHandle(hReceiveNet);
- }
- if (hReceiveNet)
- {
- WaitForSingleObject(hSendNet, INFINITE); // Wait until the end of send thread
- CloseHandle(hSendNet);
- }
- if (hClientSocket != INVALID_SOCKET)
- {
- if (shutdown(hClientSocket, SD_RECEIVE) == SOCKET_ERROR)
- {
- if ((Error = WSAGetLastError()) != WSAENOTCONN) // WSAENOTCONN means that the connection was not established,
- // so the shut down was senseless
- _tprintf(_T("shutdown() failed, error %d\n"), WSAGetLastError());
- }
- closesocket(hClientSocket);
- }
- WSACleanup(); // clean Windows sockets support
- CloseHandle(hStopCommandGot);
- CloseHandle(hCommandGot);
- CloseHandle(hCommandProcessed);
- CloseHandle(hConnectCommandGot);
- return 0;
- }
- //**************************************************************************************************************
- // KEYBOARD READING THREAD
- //**************************************************************************************************************
- unsigned int __stdcall ReadKeyboard(void* pArguments)
- {
- DWORD nReadChars;
- HANDLE KeyboardEvents[2];
- KeyboardEvents[1] = hCommandProcessed;
- KeyboardEvents[0] = hStopCommandGot;
- DWORD WaitResult;
- //
- // Reading loop
- //
- while (TRUE)
- {
- WaitResult = WaitForMultipleObjects(2, KeyboardEvents,
- FALSE, // wait until one of the events becomes signaled
- INFINITE);
- // Waiting until hCommandProcessed or hStopCommandGot becomes signaled. Initially hCommandProcessed
- // is signaled, so at the beginning WaitForMultipleObjects() returns immediately with WaitResult equal
- // with WAIT_OBJECT_0 + 1.
- if (WaitResult == WAIT_OBJECT_0)
- return 0; // Stop command, i.e. hStopCommandGot is signaled
- else if (WaitResult == WAIT_OBJECT_0 + 1)
- { // If the signaled event is hCommandProcessed, the WaitResult is WAIT_OBJECT_0 + 1
- _tprintf(_T("Insert command\n"));
- if (!ReadConsole(hStdIn, CommandBuf, 80, &nReadChars, NULL))
- { // The problem is that when we already are in this function, the only way to leave it
- // is to type something and then press ENTER. So we cannot step into this function at any moment.
- // WaitForMultipleObjects() prevents it.
- _tprintf(_T("ReadConsole() failed, error %d\n"), GetLastError());
- return 1;
- }
- CommandBuf[nReadChars - 2] = 0; // The command in buf ends with "\r\n", we have to get rid of them
- ResetEvent(hCommandProcessed);
- // Set hCommandProcessed to non-signaled. Therefore WaitForMultipleObjects() blocks the keyboard thread.
- // When the main thread has ended the analyzing of command, it sets hCommandprocessed or hStopCommandGot
- // to signaled and the keyboard thread can continue.
- SetEvent(hCommandGot);
- // Set hCommandGot event to signaled. Due to that WaitForSingleObject() in the main thread
- // returns, the waiting stops and the analyzing of inserted command may begin
- }
- else
- { // waiting failed
- _tprintf(_T("WaitForMultipleObjects()failed, error %d\n"), GetLastError());
- return 1;
- }
- }
- return 0;
- }
- //********************************************************************************************************************
- // TCP/IP INFO RECEIVING THREAD
- //********************************************************************************************************************
- unsigned int __stdcall ReceiveNet(void* pArguments)
- {
- //
- // Preparations
- //
- WSABUF DataBuf; // Buffer for received data is a structure
- char ArrayInBuf[2048];
- DataBuf.buf = &ArrayInBuf[0];
- DataBuf.len = 2048;
- DWORD nReceivedBytes = 0, ReceiveFlags = 0;
- HANDLE NetEvents[2];
- NetEvents[0] = hStopCommandGot;
- WSAOVERLAPPED Overlapped;
- memset(&Overlapped, 0, sizeof Overlapped);
- Overlapped.hEvent = NetEvents[1] = WSACreateEvent(); // manual and nonsignaled
- DWORD Result, Error;
- wchar_t *identifier = L"Identify";
- wchar_t *DataPointer;
- int loendur = 0;
- //
- // Receiving loop
- //
- while (TRUE)
- {
- Result = WSARecv(hClientSocket,
- &DataBuf,
- 1, // no comments here
- &nReceivedBytes,
- &ReceiveFlags, // no comments here
- &Overlapped,
- NULL); // no comments here
- if (Result == SOCKET_ERROR)
- { // Returned with socket error, let us examine why
- if ((Error = WSAGetLastError()) != WSA_IO_PENDING)
- { // Unable to continue, for example because the server has closed the connection
- _tprintf(_T("WSARecv() failed, error %d\n"), Error);
- goto out;
- }
- DWORD WaitResult = WSAWaitForMultipleEvents(2, NetEvents, FALSE, WSA_INFINITE, FALSE); // wait for data
- switch (WaitResult) // analyse why the waiting ended
- {
- case WAIT_OBJECT_0:
- // Waiting stopped because hStopCommandGot has become signaled, i.e. the user has decided to exit
- goto out;
- case WAIT_OBJECT_0 + 1:
- // Waiting stopped because Overlapped.hEvent is now signaled, i.e. the receiving operation has ended.
- // Now we have to see how many bytes we have got.
- WSAResetEvent(NetEvents[1]); // to be ready for the next data package
- if (WSAGetOverlappedResult(hClientSocket, &Overlapped, &nReceivedBytes, FALSE, &ReceiveFlags))
- {
- _tprintf(_T("%d bytes received\n"), nReceivedBytes);
- // Here should follow the processing of received data
- DataPointer = (wchar_t*)(DataBuf.buf + 4);
- //_tprintf("%d\n", *(DataBuf.buf) ); //esimesel kohal on arv, palju baite seal on
- _tprintf("%ls\n", DataPointer ); //_T teeb wide characterideks (wchar_t) on cast e. võta selle tagumist asja, kui wide pointerit
- //Datapointer peaks välja printima terve sõna, aga prindib ainult 1 tähe
- for (loendur = 0; loendur < nReceivedBytes; loendur++)
- {
- _tprintf(_T("%02x "), *(DataBuf.buf+ loendur));
- //_tprintf(_T("%s"), (DataBuf.buf + loendur));
- }
- _tprintf("\n");
- if(!wcscmp(DataPointer, identifier)) //detectime, kas sisendiks tuli Identify
- {
- _tprintf("Identity detected!!\n");
- //siia peaks tulema event, et saatja saadaks parooli
- SetEvent(hSendPassword);
- }
- break;
- }
- else
- { // Fatal problems
- _tprintf(_T("WSAGetOverlappedResult() failed, error %d\n"), GetLastError());
- goto out;
- }
- default: // Fatal problems
- _tprintf(_T("WSAWaitForMultipleEvents() failed, error %d\n"), WSAGetLastError());
- goto out;
- }
- }
- else
- { // Returned immediately without socket error
- if (!nReceivedBytes)
- { // When the receiving function has read nothing and returned immediately, the connection is off
- _tprintf(_T("Server has closed the connection\n"));
- goto out;
- }
- else
- {
- _tprintf(_T("%d bytes received\n"), nReceivedBytes);
- // Here should follow the processing of received data
- }
- }
- }
- out:
- WSACloseEvent(NetEvents[1]);
- return 0;
- }
- //********************************************************************************************************************
- // TCP/IP INFO SENDING THREAD
- //********************************************************************************************************************
- unsigned int __stdcall SendNet(void* pArguments)
- {
- HANDLE OutputEvents[2];
- OutputEvents[0] = hStopCommandGot;
- OutputEvents[1] = hConnectCommandGot;
- //sending loop starts here
- while (true)
- {
- DWORD WaitResult = WaitForMultipleObjects(2, OutputEvents, FALSE, INFINITE);
- switch (WaitResult) //vastavalt sellele, mis hetkel waitresult on, on tegevus
- {
- case WAIT_OBJECT_0: //siin lahkume threadist
- {
- return 0;
- }
- case WAIT_OBJECT_0 + 1:
- {
- //siin hakkab saatmine peale
- _tprintf("Siin hakkab peale serveriga ühenduse loomine\n");
- _tprintf("Siin peaks kontrollima, kas ühendus on juba loodud\n");
- _tprintf("Siin peaks ootama idenfity s6numi tulemist\n");
- //siin saatmine lõppenud
- ResetEvent(hConnectCommandGot);
- }
- break;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement