上机考试作弊,也不是不可以呢

前言

  这学期的C++课学校用了北理工的一套软件,大概一两周就有一次上机考试,软件的防作弊机制就是每个学号绑定一个IP地址,单学号登录多IP、单IP被多个学号登录都会触发重修小彩蛋。不过,正所谓时势造英雄,当人人都在抱怨的时候为什么不想一个脱离防作弊机制的手段呢?

  本文将介绍我前段时间写的一个程序,基于TCP的Winsock编程实现文件的传送。考试时大家埋头思索,这时候把答案通过IP地址传送给喜欢的妹子,脱单似乎就近在咫尺了啊。

 

思路

  Winsock的学习看微软官网手册就够了,一步一步跟着敲下来,基本上就算是入门了。

  下面简单讲一下Winsock编程的基本思路:

  Server端:创建嵌套字并初始化,创建socket,初始化socket(将端口号及IP地址绑定),listen监听,accept不断接受连接,接受到连接后,捕获socket,recv获得内容,通信完成后关闭socket。

  Client端:创建嵌套字并初始化,创建socket,绑定端口号及目标IP地址,connect连接服务器,send发送消息,通信结束后关闭socket。

完整代码

使用软件:codeblocks

用户端:TransferFile-Client.cpp

  1 // TransferFile-Client.cpp:Define the entry point for the console application.  
  2 // Program Function : Transfer file by C/S : Part Client  
  3 // Author : zhaoyixiang  
  4 // E-mail : [email protected]  
  5 // Date : 2018-5-1  
  6   
  7 #define _WIN32_WINNT  0x501  
  8 #include <winsock2.h>  
  9 #include <ws2tcpip.h>  
 10 #include <iphlpapi.h>  
 11 #include <stdio.h>  
 12 #include <cstring>  
 13   
 14 #pragma comment(lib, "Ws2_32.lib")  
 15   
 16 #define DEFAULT_PORT "27015"  
 17 #define DEFAULT_BUFLEN 512  
 18   
 19 using namespace std;  
 20   
 21 int main(int argc, char const *argv[])  
 22 {  
 23     WSADATA wsaData;  
 24   
 25     int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);  
 26     if (iResult != 0)  
 27     {  
 28         printf("WSAStartup failed: %d\n", iResult);  
 29         return 1;  
 30     }  
 31   
 32   
 33     /* 
 34         Creating a Socket for the Client 
 35         Declare an addrinfo object that contains a sockaddr structure and initialize these values. 
 36         For this application, the Internet address family is unspecified 
 37         so that either an IPv6 or IPv4 address can be returned. 
 38         The application requests the socket type to be a stream socket for the TCP protocol. 
 39     */  
 40     struct addrinfo *result = NULL, *ptr = NULL, hints;  
 41     ZeroMemory(&hints, sizeof(hints));  
 42     hints.ai_family = AF_UNSPEC;  
 43     hints.ai_socktype = SOCK_STREAM;  
 44     hints.ai_protocol = IPPROTO_TCP;  
 45   
 46     // Resolve the server address and port  
 47     iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);  
 48     if (iResult != 0)  
 49     {  
 50         printf("getaddrinfo failed: %d\n", iResult);  
 51         WSACleanup();  
 52         return 1;  
 53     }  
 54   
 55       
 56   
 57     char temp[DEFAULT_BUFLEN];  
 58     strcpy(temp, "main.cpp");  
 59     // create file  
 60     FILE * fp = fopen(temp, "rb"); // binary mode for read  
 61     if(fp == NULL)  
 62     {  
 63         printf("open file %s failed\n", temp);  
 64         return -1;  
 65     }  
 66   
 67     SOCKET ConnectSocket = INVALID_SOCKET;  
 68     ptr = result;  
 69     ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);  
 70     if (ConnectSocket == INVALID_SOCKET)  
 71     {  
 72         printf("Error at socket(): %ld\n", WSAGetLastError());  
 73         freeaddrinfo(result);  
 74         WSACleanup();  
 75         return 1;  
 76     }  
 77   
 78   
 79     /* 
 80         Connecting to a Socket 
 81         For a client to communicate on a network, it must connect to a server. 
 82     */  
 83     iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);  
 84     if (iResult == SOCKET_ERROR)  
 85     {  
 86         printf("Unable to connect to server!\n");  
 87         WSACleanup();  
 88         return 1;  
 89     }  
 90   
 91   
 92     /* 
 93         Sending and Receiving Data on the Client 
 94     */  
 95     int recvbuflen = DEFAULT_BUFLEN;  
 96     char recvbuf[DEFAULT_BUFLEN];  
 97     char sendbuf[DEFAULT_BUFLEN];  
 98   
 99     int num = 0;  
100     while(!feof(fp))  
101     {  
102         num = fread(temp, 1, DEFAULT_BUFLEN, fp);  
103         send(ConnectSocket, temp, num, 0);  
104     }  
105     printf("server file transfer success\n");  
106   
107     fclose(fp);  
108       
109   
110     iResult = shutdown(ConnectSocket, SD_SEND);  
111     if (iResult == SOCKET_ERROR)  
112     {  
113         printf("Shutdown failed: %d\n", WSAGetLastError());  
114         closesocket(ConnectSocket);  
115         WSACleanup();  
116         return 1;  
117     }  
118   
119     closesocket(ConnectSocket);  
120   
121   
122     WSACleanup();  
123     return 0;  
124 }  

服务端:TransferFile-Server.cpp

  1 // TranferFile-Server.cpp:Define the entry point for the console application.  
  2 // Program Function : Transfer file by C/S : Part Server  
  3 // Author : zhaoyixiang  
  4 // E-mail : [email protected]  
  5 // Date : 2018-5-1  
  6   
  7 #define _WIN32_WINNT  0x501  
  8 #include <winsock2.h>  
  9 #include <ws2tcpip.h>  
 10 #include <iphlpapi.h>  
 11 #include <stdio.h>  
 12 #include <cstring>  
 13   
 14 #pragma comment(lib, "Ws2_32.lib")  
 15   
 16 #define DEFAULT_PORT "27015"  
 17 #define DEFAULT_BUFLEN 512  
 18   
 19 using namespace std;  
 20   
 21 int main(int argc, char const *argv[])  
 22 {  
 23     WSADATA wsaData;  
 24   
 25     int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);  
 26     if (iResult != 0)  
 27     {  
 28         printf("WSAStartup failed: %d\n", iResult);  
 29         return 1;  
 30     }  
 31   
 32   
 33     char file_name[DEFAULT_BUFLEN];  
 34     char temp[DEFAULT_BUFLEN];  
 35     strcpy(file_name, "receive test");  
 36     //create file  
 37     FILE *fp = fopen(file_name, "wb");  
 38     if(fp == NULL)  
 39     {  
 40         printf("create file %s failed\n", file_name);  
 41         return -1;  
 42     }  
 43   
 44   
 45     /* 
 46         Creating a Socket for the Server 
 47     */  
 48     struct addrinfo *result = NULL, hints;  
 49   
 50     ZeroMemory(&hints, sizeof(hints));  
 51     hints.ai_family = AF_INET;  
 52     hints.ai_socktype = SOCK_STREAM;  
 53     hints.ai_protocol = IPPROTO_TCP;  
 54     hints.ai_flags = AI_PASSIVE;  
 55   
 56     iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);  
 57     if (iResult != 0)  
 58     {  
 59         printf("getaddrinfo failed: %d\n", iResult);  
 60         WSACleanup();  
 61         return 1;  
 62     }  
 63     SOCKET ListenSocket = INVALID_SOCKET;  
 64     ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);  
 65     if (ListenSocket == INVALID_SOCKET)  
 66     {  
 67         printf("Error at sock(): %ld\n", WSAGetLastError());  
 68         freeaddrinfo(result);  
 69         WSACleanup();  
 70         return 1;  
 71     }  
 72   
 73   
 74     /* 
 75         Binding a Socket 
 76         For a server to accept client connections, 
 77         it must be bound to a network address within the system. 
 78     */  
 79     iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);  
 80     if (iResult == SOCKET_ERROR)  
 81     {  
 82         printf("bind failed: %d\n", WSAGetLastError());  
 83         freeaddrinfo(result);  
 84         closesocket(ListenSocket);  
 85         WSACleanup();  
 86         return 1;  
 87     }  
 88     freeaddrinfo(result);  
 89   
 90   
 91   
 92     /* 
 93         Listening on a Socket 
 94         After the socket is bound to an IP address and port on the system, 
 95         the server must then listen on that IP address and port 
 96         for incoming connection requests. 
 97     */  
 98     if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR)  
 99     {  
100         printf("Listen failed with error: %d\n", WSAGetLastError());  
101         closesocket(ListenSocket);  
102         WSACleanup();  
103         return 1;  
104     }  
105   
106   
107     /* 
108         Accepting a Connection 
109         Once the socket is listening for a connection, 
110         the program must handle connection requests on that socket. 
111     */  
112     SOCKET ClientSocket;  
113     ClientSocket = INVALID_SOCKET;  
114     ClientSocket = accept(ListenSocket, NULL, NULL);  
115     if (ClientSocket == INVALID_SOCKET)  
116     {  
117         printf("accept failed: %d\n", WSAGetLastError());  
118         closesocket(ListenSocket);  
119         WSACleanup();  
120         return 1;  
121     }  
122   
123   
124     /* 
125         Receiving and Sending Data on the Server 
126     */  
127     char recvbuf[DEFAULT_BUFLEN];  
128     int iSendResult;  
129     int recvbuflen = DEFAULT_BUFLEN;  
130   
131   
132     //receive data from server  
133     int num = 0;  
134     while (1)  
135     {  
136         num = recv(ClientSocket, temp, DEFAULT_BUFLEN, 0);  
137         if(0 == num)  
138             break;  
139         fwrite(temp, 1, num, fp);  
140     }  
141     printf("transmission done\n");  
142   
143     fclose(fp);  
144   
145   
146     // shutdown the connection for sending since no more data will be sent  
147     // the client can still use the ConnectSocket for receiving data  
148     iResult = shutdown(ClientSocket, SD_SEND);  
149     if (iResult == SOCKET_ERROR)  
150     {  
151         printf("shutdown failed: %d\n", WSAGetLastError());  
152         closesocket(ClientSocket);  
153         WSACleanup();  
154         return 1;  
155     }  
156   
157     // cleanup  
158     closesocket(ClientSocket);  
159   
160   
161   
162     WSACleanup();  
163   
164     return 0;  
165 }  

注意事项

  codeblocks调用API还是比较麻烦的

  #include <winsock2.h>

  #pragma comment(lib, "Ws2_32.lib")

  以上是常规操作,而cb想编译成功的话则需进行一下操作:

  选择project -> Build options

  

  Linker settings -> other linker options -> 输入-lws2_32 -> OK

使用方法

  先运行server文件,再用命令行运行client文件并输入接受方的IP地址,事先准备好的main.cpp(可以更换名称)即可发送。

  Teamwork时,自己持有Client文件,给妹子Server文件,然后趁着月黑风高为所欲为。

补充

  当然了,真正操作的时候不要傻乎乎的将生成的TransferFile-Client.exe / TransferFile-Server.exe文件直接摆在桌面上,监考老师只要学过英语就能发现你在作弊好吧!!!

  到网上搜一个教程把文件图标改了,再把文件名改成常用软件名,例如notepad++,这样老师一般不会注意到。

总结

  据说点赞的人一周之内都会脱单。。。(逃

猜你喜欢

转载自www.cnblogs.com/henuzyx/p/9049376.html