widows下使用socket套接字進行網絡通信的步驟與Linux下差異不大,基本的調用流程也是相似的,即使內部的實現有所不同。
以下是服務器端的代碼實現:
#include <iostream>
#include <stdlib.h>
#include <WinSock2.h>
using namespace std;
int main(int argc, char* argv[])
{
if (argc != 2)
{
cout << "invalid parameter! add port!" << endl;
exit(1);
}
WSADATA wsaData;
SOCKET servSock, clntSock;
SOCKADDR_IN servAddr, clntAddr;
int clntAddrLen;
// 設置程序中用到的Winsock版本,並初始化相應版本的庫
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
cout << "WSAStartup() error" << endl;
exit(1);
}
// 創建socket套接字
servSock = socket(PF_INET, SOCK_STREAM, 0);
if (servSock == INVALID_SOCKET)
{
cout << "socket() error" << endl;
exit(1);
}
// 設置服務端的地址信息:IP、端口、協議族
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(atoi(argv[1]));
// 綁定IP和端口
if (bind(servSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
cout << "bind() error" << endl;
exit(1);
}
// 在所綁定的端口號做監聽
if (listen(servSock, 5) == SOCKET_ERROR)
{
cout << "listen() error" << endl;
exit(1);
}
// 接收來自客戶端的連接請求
clntAddrLen = sizeof(clntAddr);
clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &clntAddrLen);
if (clntSock == INVALID_SOCKET)
{
cout << "accept() error" << endl;
exit(1);
}
// 向客戶端發送數據
char message[] = "Hello, It's servers!";
send(clntSock, message, sizeof(message), 0);
// 關閉套接字連接
closesocket(servSock);
closesocket(clntSock);
// 註銷使用的Winsock庫
WSACleanup();
return EXIT_SUCCESS;
}
以下是客戶端的代碼實現:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <WinSock2.h>
using namespace std;
int main(int argc, char* argv[])
{
// 檢查輸入參數的合法性
if (argc != 3)
{
cout << "invalid parameter! add ip and port!" << endl;
exit(1);
}
WSADATA wsaData;
SOCKET clntSocket;
SOCKADDR_IN servAddr;
// 設置程序中用到的Winsock版本,並初始化相應版本的庫
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
cout << "WSAStartup() error" << endl;
exit(1);
}
// 創建socket套接字
clntSocket = socket(PF_INET, SOCK_STREAM, 0);
if (clntSocket == INVALID_SOCKET)
{
cout << "socket() error" << endl;
exit(1);
}
// 設置服務器端的地址信息:IP、端口、協議族
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
// 創建連接
if (connect(clntSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
cout << "connect() error" << endl;
exit(1);
}
// 接收來自服務器端的數據
char message[100] = { 0 };
int msglen = recv(clntSocket, message, sizeof(message) - 1, 0);
if (msglen == -1)
{
cout << "recv() error" << endl;
exit(1);
}
cout << "msg from server : " << message << endl;
// 關閉套接字連接
closesocket(clntSocket);
// 註銷使用的Winsock庫
WSACleanup();
return 0;
}
在VS中編譯後,生成可執行文件。然後使用cmd,分別運行客戶端和服務器端程序,服務器端監聽8888端口,而客戶端綁定本地IP和8888端口,與服務器端建立鏈接。
客戶端程序執行結果:建立連接成功後,收到來自服務器端的信息數據。
服務器端執行結果:開始時創建套接字,然後等待客戶端的連接,沒有任何輸出,一旦客戶端連接成功後,發送消息,然後直接運行結束。
謝謝閱讀。