有了上次socket的基礎知識,網路編程01 可以寫一個簡單的聊天程式,隨便復習一下基礎知識,
1.執行緒
我們要實作可以同時發送和接收資訊,就需要多執行緒了,一個用于發,一個用于收,
這次用CreateThread來創建執行緒,函式原型
HANDLE WINAPI CreateThread ( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId ); 函式看著復雜其實用起來很簡單,只需要關心傳入什么函式,函式引數是什么, 1.第一個引數表示執行緒內核物件的安全屬性,一般傳入NULL表示使用默認設定 2.第二個引數表示執行緒堆疊空間大小,傳入0表示使用默認大小 3.第三個引數表示新執行緒所執行的執行緒函式地址(函式的名字),多個執行緒可以使用同一個函式地址 4.第四個引數是傳給執行緒函式的引數, 5.第五個引數指定什么時候呼叫執行緒,為0表示執行緒創建之后立即就可以進行呼叫, 6.第六個引數回傳執行緒的ID號,傳入NULL表示不需要回傳該執行緒ID號 2.服務器端代碼 我們把發送資訊和接收資訊的功能封裝成兩個函式作為執行緒使用,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),目標用戶的電腦馬上就會關機,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/33475.html
標籤:C
上一篇:C語言多檔案引數傳遞
下一篇:指標
