Du kan prøve med nedenstående program:
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
SOCKET Socket;
char IPAddressStr[128];
short SocketPort = 5011;
bool HasRxAddr = true;
struct in_addr RxAddr;
int SetupSocket();
void HandleTx(const char *text);
void HandleRx();
void ShotDown();
int main(int argc, char* argv[])
{
SetupSocket();
if(argc == 2)
{ // I'm to close the other PC
strcpy(IPAddressStr, argv[1]);
HandleTx("Please PowerOff");
HandleRx();
}
else
{ // I'm to be closed
while(1)
{
HandleRx();
}
}
}
void HandleTx(const char *text)
{
struct sockaddr_in sockaddr;
memset((char *)&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
if(IPAddressStr[0])
sockaddr.sin_addr.s_addr = inet_addr(IPAddressStr);
else if(HasRxAddr)
sockaddr.sin_addr.s_addr = RxAddr.s_addr;
else
{
std::cout << "No Peer Address" << std::endl;
return;
}
if(sockaddr.sin_addr.s_addr == INADDR_NONE)
{
std::cout << "Failed to convert IPAddress!" << std::endl;
return;
}
sockaddr.sin_port = htons(SocketPort);
if(sendto(Socket, text, strlen(text) + 1, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
{
std::cout << "SendTo Failed" << std::endl;
exit(2);
}
}
void HandleRx()
{
const int MaxLineLength = 256;
char buffer[MaxLineLength + 1];
sockaddr_in RxSockAddr;
int FromLen = sizeof(RxSockAddr);
if(recvfrom(Socket, buffer, MaxLineLength, 0, (sockaddr *)&RxSockAddr, &FromLen) != SOCKET_ERROR)
{
RxAddr = RxSockAddr.sin_addr;
HasRxAddr = true;
std::cout << "Received: " << buffer << std::endl;
if(!strcmp(buffer, "Please PowerOff"))
{
HandleTx("Received The ShutDown Message");
std::cout << "Try To Close" << std::endl;
Sleep(1000);
ShotDown();
}
else
{
HandleTx("Received Something Else");
}
}
else
{
std::cout << "Failed To Receive: " << WSAGetLastError() << std::endl;
exit(1);
}
}
int SetupSocket()
{
WSADATA wsaData;
struct sockaddr_in sockaddr;
if(WSAStartup(MAKEWORD(1, 1), &wsaData))
{
std::cout << "Failed to start WSA" << std::endl;
exit(3);
}
Socket = socket(AF_INET, SOCK_DGRAM, 0);
if(Socket == INVALID_SOCKET)
{
std::cout << "Failed To Create Socket!" << std::endl;
return 1;
}
memset((char *)&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(SocketPort);
BOOL Flag = TRUE;
setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, (char *)&Flag, sizeof(Flag));
if(bind(Socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
{
std::cout << "Failed to bind socket!" << std::endl;
return 1;
}
return 1;
}
void CleanUp()
{
if(Socket)
closesocket(Socket);
WSACleanup();
}
void ShotDown()
{
HANDLE Token;
LUID luid;
TOKEN_PRIVILEGES tp;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_WRITE, &Token))
{
std::cout << "OpenThreadToken error: " << GetLastError() << std::endl;
return;
}
if(!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid))
{
std::cout << "LookupPrivilegeValue error: " << GetLastError() << std::endl;
return;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(Token,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES )NULL,
(PDWORD )NULL);
if(GetLastError() != ERROR_SUCCESS)
{
std::cout << "AdjustTokenPrivileges error: " << std::endl;
return;
}
ExitWindowsEx(EWX_POWEROFF, 0);
}
Det er den samme kode til begge ender. Fra den ende der skal lukkes ned skal der ikke være nogen argumenter. Fra den ende hvorfra du vil lukke ned, skal du angive ip-adressen på den PC der skal slukkes som argument til programmet.