有了上次socket的基礎知識,網絡編程01 可以寫一個簡單的聊天程序,隨便複習一下基礎知識。
1.線程
我們要實現可以同時發送和接收信息,就需要多線程了,一個用於發,一個用於收。
這次用CreateThread來創建線程。函數原型
1 #include<stdio.h> 2 #include<string.h> 3 #include<WinSock2.h> 4 #pragma comment (lib,"ws2_32.lib") 5 SOCKET newSocket;//全局變量,用來通信的套接字 6 7 void recvFun();//接收信息線程 8 void sendFun();//發送信息線程 9 void createConnect();//創建通信套接字 10 11 int main() 12 { 13 HANDLE h1, h2;//線程句柄 14 createConnect(); 15 printf("連接成功...\n"); 16 //創建線程後立即運行 17 h1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sendFun, NULL, 0, NULL); 18 h2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvFun, NULL, 0, NULL); 19 WaitForSingleObject(h1, INFINITE);//會阻塞,直到線程結束 20 WaitForSingleObject(h2, INFINITE);//會阻塞,直到線程結束 21 closesocket(newSocket);//關閉套接字 22 return 0; 23 } 24 void sendFun() 25 { 26 char buf[128]; 27 while (1) 28 { 29 printf("你要發送的信息:"); 30 scanf("%s", buf); 31 send(newSocket, buf, strlen(buf) + 1, 0);//發送信息 32 } 33 } 34 35 void recvFun() 36 { 37 char buf[128]; 38 while (1) 39 { 40 recv(newSocket, buf, 128, 0);//接收信息 41 printf("%32s%s\n","接收到的信息: ", buf); 42 } 43 44 } 45 46 void createConnect() 47 { 48 SOCKET serverSocket;//監視的套接字 49 //SOCKET newSocket;//用來通信的套接字 50 SOCKADDR_IN newAddr;//保存客戶端的socket地址信息 51 SOCKADDR_IN addr;//地址結構體,包括ip port(端口) 52 WSADATA data; 53 WORD version;//socket版本 54 int info; 55 /* 56 在使用socket之前要進行版本的設定和初始化 57 看不懂不用管 58 */ 59 version = MAKEWORD(2, 2);//設定版本 60 info = WSAStartup(version, &data); 61 /*應用程序或DLL只能在一次成功的WSAStartup()調用之後 62 才能調用進一步的Windows Sockets API函數。 63 根據版本初始化 windows socket,返回0表示成功 64 */ 65 if (info != 0) 66 { 67 printf("初始化失敗\n"); 68 return; 69 } 70 if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2) 71 { 72 printf("加載失敗\n"); 73 WSACleanup(); 74 return; 75 } 76 //創建套接字,使用TCP協議 77 serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 78 addr.sin_addr.S_un.S_addr = htonl(ADDR_ANY);//表示任何的ip過來連接都接受 79 addr.sin_family = AF_INET;//使用ipv4的地址 80 addr.sin_port = htons(6666);//設定應用佔用的端口 81 bind(serverSocket, (SOCKADDR*)&addr, sizeof(SOCKADDR));//將套接字與端口6666,接收的ip綁定 82 listen(serverSocket, 3);//開始監聽,是否有客服端請求連接,最大連接數爲3 83 printf("開始監聽,等待連接..........\n"); 84 int len = sizeof(SOCKADDR); 85 newSocket = accept(serverSocket, (SOCKADDR*)&newAddr, &len); 86 }
3.客戶端代碼
客戶端和服務器端代碼差不多,也是兩個線程用於接收和發送信息。
1 #include<stdio.h> 2 #include<string.h> 3 #include<WinSock2.h> 4 #pragma comment(lib,"ws2_32.lib") 5 SOCKET clientSocket;//全局變量,用於通信的socket 6 void createConnect();//創建套接字 7 void sendFun();//發送信息線程 8 void recvFun();//接收信息線程 9 int main() 10 { 11 HANDLE h1, h2;//線程句柄,其實就是一串數字用來標識線程對象 12 createConnect();//創建套接字 13 //創建線程後立即執行 14 h1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sendFun, NULL, 0, NULL); 15 h2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvFun, NULL, 0, NULL); 16 WaitForSingleObject(h1, INFINITE);//會阻塞,直到線程運行結束 17 WaitForSingleObject(h2, INFINITE); 18 closesocket(clientSocket);//關閉套接字 19 return 0; 20 } 21 void createConnect() 22 { 23 SOCKADDR_IN addr; 24 int info; 25 WSADATA data; 26 WORD version; 27 //設定版本,與初始化 28 version = MAKEWORD(2, 2); 29 info = WSAStartup(version, &data); 30 if (info != 0) 31 { 32 printf("初始化失敗\n"); 33 return; 34 } 35 if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2) 36 { 37 printf("加載失敗\n"); 38 WSACleanup(); 39 return; 40 } 41 clientSocket = socket(AF_INET, SOCK_STREAM, 0);//創建套接字 42 //要連接的服務器的ip,因爲現在服務器端就是本機,所以寫本機ip 43 //127.0.0.1一個特殊的IP地址,表示是本機的IP地址 44 addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 45 //端口要與服務器相同,不然找不到 46 addr.sin_port = htons(6666); 47 //用IPV4地址 48 addr.sin_family = AF_INET; 49 //主動連接服務器 50 connect(clientSocket, (SOCKADDR*)&addr, sizeof(SOCKADDR)); 51 } 52 53 void sendFun() 54 { 55 char buf[128]="你是誰"; 56 while (1) 57 { 58 printf("你要發送的信息: "); 59 scanf("%s", buf); 60 //發送數據 61 send(clientSocket, buf, strlen(buf) + 1, 0); 62 } 63 } 64 65 66 void recvFun() 67 { 68 char buf[128]; 69 //接收服務發送的數據 70 while (1) 71 { 72 recv(clientSocket, buf, 128, 0);//接收數據 73 printf("%32s%s\n","接收的信息爲: ", buf); 74 } 75 }
運行結果,可以實現聊天的功能,雖然界面不行。
學了socket編程還可以實現木馬之類的東西。原理很簡單,讓目標用戶在後臺悄悄運行你的程序,在另一端你可以發送各種命令操作程序從而實現操作用戶的電腦,竊取信息。比如你發送個強制關機的命令的 str="shutdown -s -f",而目標用戶的程序接收到了這個命令並且調用了 system(str)。目標用戶的電腦馬上就會關機。