Winsock编程原理——面向连接
生活随笔
收集整理的這篇文章主要介紹了
Winsock编程原理——面向连接
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Winsock編程原理——面向連接
Windows Sockets使用套接字進行編程,套接字編程是面向客戶端/服務器模型而設計的,因此系統中需要客戶端和服務器兩個不同類型的進程,根據連接類型的不同,對于面向連接的TCP服務和無連接的UDP服務,服務器分別采取不同的處理操作來對客戶提供服務。
面向連接
服務器 socket() -> bind() -> listen() -> accept() -> recv()/send() -> closesocket(); 創建套接字,綁定IP和端口,偵聽,接收連接,收發消息,關閉連接 客戶端 socket() -> connet() -> send()/recv() -> closesocket(); 創建套接字,連接服務器,發收消息,關閉連接 一對一的模式,一個服務器, 一個客戶端 1 /* 2 服務器端代碼 3 */ 4 5 #include<Winsock2.h> 6 #include<stdio.h> 7 #include<stdlib.h> 8 #pragma comment(lib,"ws2_32.lib") 9 #define PORT 5000 10 11 void main() 12 { 13 int port = PORT; //端口 14 WSADATA wsaData; //存儲系統傳回的關于Winsock的資料 15 SOCKET sListen, sAccept; //套接字 16 int iLen; //客戶地址長度 17 int iSend; //發送數據長度 18 char buf[] = "Hello, How are you!"; //需要發送的信息 19 struct sockaddr_in serv, cliet; //服務器、客戶的地址 20 21 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //函數WSAStartup用以打開Winsock 22 { 23 printf("Winsock load failed\n"); 24 return; 25 } 26 27 sListen = socket(AF_INET, SOCK_STREAM, 0); //創建套接字,TCP協議 28 if (sListen == INVALID_SOCKET) //socket調用成功返回套接字對象,失敗返回INVALID_SOCKET 29 { 30 printf("socket failed:%d\n", WSAGetLastError()); 31 return; 32 } 33 34 serv.sin_family = AF_INET; //網絡中標識不同設備使用的地址類型,對于IP地址,類型是AF_INET 35 serv.sin_port = htons(port); //socket對應的端口號 36 serv.sin_addr.s_addr = htonl(INADDR_ANY); //封裝了IP地址 37 if (bind(sListen, (LPSOCKADDR)&serv, sizeof(serv)) == SOCKET_ERROR) //綁定套接字 38 { 39 printf("bind() failed:%d\n", WSAGetLastError()); 40 return; 41 } 42 43 if (listen(sListen, 5) == SOCKET_ERROR) //監聽 44 { 45 printf("listen() failed:%d\n", WSAGetLastError()); 46 return; 47 } 48 49 iLen = sizeof(cliet); //初始化客戶地址長度 50 51 while (1) //進入循環,等待客戶連接請求 52 { 53 sAccept = accept(sListen, (struct sockaddr*)&cliet, &iLen); //客戶端的套接字 54 if (sAccept == INVALID_SOCKET) //接受連接請求失敗 55 { 56 printf("accept() failed:%d\n", WSAGetLastError()); 57 break; 58 } 59 //輸出客戶端IP、端口 60 printf("accept() client IP:[%s], port:[%d]\n", inet_ntoa(cliet.sin_addr), ntohs(cliet.sin_port)); 61 62 //給連接的客戶發送消息 63 iSend = send(sAccept, buf, sizeof(buf), 0); 64 if (iSend == SOCKET_ERROR) 65 { 66 printf("send() failed:%d\n", WSAGetLastError()); 67 break; 68 } 69 else if (iSend == 0) 70 break; 71 else 72 printf("send() byte:%d\n", send); 73 74 closesocket(sListen); //關閉套接字 75 closesocket(sAccept); //關閉套接字 76 WSACleanup(); //關閉Winsock 77 } 78 while (1); 79 } server 1 /* 2 客戶端程序 3 */ 4 #include<WinSock2.h> 5 #include<stdio.h> 6 #pragma comment(lib,"ws2_32.lib") 7 #define PORT 5000 8 #define BUFFER 1024 9 10 void main(int argc,char *argv[]) 11 { 12 WSADATA wsaData; 13 SOCKET client; 14 int port = PORT; 15 int iLen; //從服務器接收的數據長度 16 char buf[BUFFER]; //接收數據的緩沖 17 struct sockaddr_in serv; //服務器端地址 18 memset(buf, 0, sizeof(buf)); //接受數據緩沖區初始化 19 20 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //函數WSAStartup用以打開Winsock 21 { 22 printf("Winsock load failed\n"); 23 return; 24 } 25 26 serv.sin_family = AF_INET; //需要連接服務器地址信息,AF_INET表示IP協議 27 serv.sin_port = htons(port); //端口 28 // serv.sin_addr.s_addr = inet_addr(argv[1]); //IP地址,轉為二進制表示的字節IP地址,argv表示cmd下輸入的參數 29 serv.sin_addr.s_addr = inet_addr("10.100.211.224"); 30 client = socket(AF_INET, SOCK_STREAM, 0); //客戶端套接字,流套接字表示使用TCP協議 31 if (client == INVALID_SOCKET) //創建套接字失敗 32 { 33 printf("socket() failed:%d\n", WSAGetLastError()); 34 return; 35 } 36 37 //連接服務器 38 if (connect(client, (struct sockaddr*)&serv, sizeof(serv)) == INVALID_SOCKET) 39 { 40 printf("connet() failed:%d\n", WSAGetLastError); 41 return; 42 } 43 else 44 { 45 iLen = recv(client, buf, sizeof(buf), 0); //從服務器接收數據 46 if (iLen = 0) 47 return; 48 else if (iLen == SOCKET_ERROR) 49 { 50 printf("recv() failed:%d\n", WSAGetLastError()); 51 return; 52 } 53 printf("recv() data from server:%s\n", buf); 54 } 55 56 closesocket(client); //關閉套接字 57 WSACleanup; //關閉Winsock 58 59 // system("pause"); //程序暫停 60 printf("press any key to continue"); //讓程序等待 61 while (1); 62 } client加入多線程機制,一個服務器,多個客戶端??
1 /* 2 服務器端代碼 3 */ 4 5 #include<Winsock2.h> 6 #include <windows.h> 7 #include<stdio.h> 8 #include<stdlib.h> 9 #pragma comment(lib,"ws2_32.lib") 10 #define PORT 5000 11 class MySocket 12 { 13 private: 14 SOCKET accept; 15 struct sockaddr_in clientAddr; 16 public: 17 MySocket(SOCKET a, struct sockaddr_in c) 18 { 19 accept = a; 20 clientAddr = c; 21 } 22 void setAccept(SOCKET a) 23 { 24 accept = a; 25 } 26 void setClientAddr(struct sockaddr_in c) 27 { 28 clientAddr = c; 29 } 30 SOCKET getAccept() 31 { 32 return accept; 33 } 34 struct sockaddr_in getClientAddr() 35 { 36 return clientAddr; 37 } 38 }; 39 DWORD WINAPI ThreadFuc(LPVOID lparam) 40 { 41 MySocket* mSocket = (MySocket*)lparam; //接收主線程傳來的參數 42 char buf[] = "Hello, How are you!"; //需要發送的信息 43 int iSend = 0; 44 //輸出客戶端IP、端口 45 printf("accept() client IP:[%s], port:[%d]\n", inet_ntoa(mSocket->getClientAddr().sin_addr), ntohs(mSocket->getClientAddr().sin_port)); 46 //給連接的客戶發送消息 47 iSend = send(mSocket->getAccept(), buf, sizeof(buf), 0); 48 if (iSend == SOCKET_ERROR) 49 { 50 printf("send() failed:%d\n", WSAGetLastError()); 51 } 52 else if (iSend == 0) 53 printf("send() failed,no message send successfully\n"); 54 else 55 printf("send() byte:%d\n", send); 56 closesocket(mSocket->getAccept()); //關閉套接字 57 return 0; 58 } 59 60 void main() 61 { 62 int port = PORT; //端口 63 WSADATA wsaData; //存儲系統傳回的關于Winsock的資料 64 SOCKET sListen, sAccept; //套接字 65 int iLen; //客戶地址長度 66 struct sockaddr_in serv, cliet; //服務器、客戶的地址 67 68 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //函數WSAStartup用以打開Winsock 69 { 70 printf("Winsock load failed\n"); 71 return; 72 } 73 74 sListen = socket(AF_INET, SOCK_STREAM, 0); //創建套接字,TCP協議 75 if (sListen == INVALID_SOCKET) //socket調用成功返回套接字對象,失敗返回INVALID_SOCKET 76 { 77 printf("socket failed:%d\n", WSAGetLastError()); 78 return; 79 } 80 81 serv.sin_family = AF_INET; //網絡中標識不同設備使用的地址類型,對于IP地址,類型是AF_INET 82 serv.sin_port = htons(port); //socket對應的端口號 83 serv.sin_addr.s_addr = htonl(INADDR_ANY); //封裝了IP地址 84 if (bind(sListen, (LPSOCKADDR)&serv, sizeof(serv)) == SOCKET_ERROR) //綁定套接字 85 { 86 printf("bind() failed:%d\n", WSAGetLastError()); 87 return; 88 } 89 90 if (listen(sListen, 5) == SOCKET_ERROR) //監聽 91 { 92 printf("listen() failed:%d\n", WSAGetLastError()); 93 return; 94 } 95 96 iLen = sizeof(cliet); //初始化客戶地址長度 97 98 while (1) //進入循環,等待客戶連接請求 99 { 100 sAccept = accept(sListen, (struct sockaddr*)&cliet, &iLen); //客戶端的套接字 101 if (sAccept == INVALID_SOCKET) //接受連接請求失敗 102 { 103 printf("accept() failed:%d\n", WSAGetLastError()); 104 break; 105 } 106 else 107 { 108 MySocket* mSocket = new MySocket(sAccept, cliet); 109 HANDLE thread = CreateThread(NULL, NULL, ThreadFuc, mSocket, NULL, NULL); 110 // closesocket(sAccept);不能關閉,關閉則不行。 111 } 112 } 113 closesocket(sListen); //關閉套接字 114 WSACleanup(); //關閉Winsock 115 while (1); 116 } server 1 /* 2 客戶端程序 3 */ 4 #include<WinSock2.h> 5 #include<stdio.h> 6 #pragma comment(lib,"ws2_32.lib") 7 #define PORT 5000 8 #define BUFFER 1024 9 10 void main(int argc, char *argv[]) 11 { 12 WSADATA wsaData; 13 SOCKET client; 14 int port = PORT; 15 int iLen; //從服務器接收的數據長度 16 char buf[BUFFER]; //接收數據的緩沖 17 struct sockaddr_in serv; //服務器端地址 18 memset(buf, 0, sizeof(buf)); //接受數據緩沖區初始化 19 20 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //函數WSAStartup用以打開Winsock 21 { 22 printf("Winsock load failed\n"); 23 return; 24 } 25 26 serv.sin_family = AF_INET; //需要連接服務器地址信息,AF_INET表示IP協議 27 serv.sin_port = htons(port); //端口 28 // serv.sin_addr.s_addr = inet_addr(argv[1]); //IP地址,轉為二進制表示的字節IP地址,argv表示cmd下輸入的參數 29 serv.sin_addr.s_addr = inet_addr("192.168.0.21"); 30 client = socket(AF_INET, SOCK_STREAM, 0); //客戶端套接字,流套接字表示使用TCP協議 31 if (client == INVALID_SOCKET) //創建套接字失敗 32 { 33 printf("socket() failed:%d\n", WSAGetLastError()); 34 return; 35 } 36 37 //連接服務器 38 if (connect(client, (struct sockaddr*)&serv, sizeof(serv)) == INVALID_SOCKET) 39 { 40 printf("connet() failed:%d\n", WSAGetLastError); 41 return; 42 } 43 else 44 { 45 iLen = recv(client, buf, sizeof(buf), 0); //從服務器接收數據 46 if (iLen = 0) 47 return; 48 else if (iLen == SOCKET_ERROR) 49 { 50 printf("recv() failed:%d\n", WSAGetLastError()); 51 return; 52 } 53 printf("recv() data from server:%s\n", buf); 54 } 55 56 closesocket(client); //關閉套接字 57 WSACleanup; //關閉Winsock 58 59 // system("pause"); //程序暫停 60 printf("press any key to continue"); //讓程序等待 61 while (1); 62 } client?
?
轉載于:https://www.cnblogs.com/starf/p/3623421.html
總結
以上是生活随笔為你收集整理的Winsock编程原理——面向连接的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux定时任务的设置
- 下一篇: 基于Windows Server 200