用Socket API 建立簡易TCP服務端、客戶端
服務器程序工作
1.初始化 Winsock庫
2.創建監聽套接字(socket()函數)
3.填寫要綁定的本地地址結構(bind()函數)
4.給監聽套接字綁定本地IP地址
5.開始監聽(listen()函數)
6.循環執行 調用accept()函數接收客戶端連接請求,如果accept()函數返回成功.則調用send()函數向客戶端發送數據或者調用recv()函數從客戶端接收數據
客戶端程序工作
1.初始化 Winsock庫
2.創建通信套接字(socket()函數)
3.填寫要連接的服務器的地址結構
4.與服務器建立連接(connect()函數)
5.調用recv()函數接收服務器數據,send()函數發送數據給服務器
服務器程序代碼:
// Server.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib, "WS2_32.lib")
//表示鏈接WS2_32.lib這個庫。
#define PORT 1024
int main()
{
SOCKET sock_server, newsock;
struct sockaddr_in server_addr, client_addr;
char msg[] = { "Hello clinet" };
// 初始化 winsock2.dll[12/27/2017 MagicScaring]
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2); //生成版本號
if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
cout << "加載 winsock.dll失敗" << endl;
return 0;
}
// 創建套接字 [12/27/2017 MagicScaring]
if ((sock_server = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
{
cout << "創建套接字失敗! 錯誤代碼:" << WSAGetLastError() << endl;
WSACleanup(); //註銷WinSock動態鏈接庫
return 0;
}
// 填寫需要綁定的本地地址 [12/27/2017 MagicScaring]
int addr_len = sizeof(struct sockaddr_in);
memset((void*)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock_server, (struct sockaddr*)&server_addr, addr_len) != 0)
{
cout << "綁定失敗!錯誤代碼:" << WSAGetLastError() << endl;
closesocket(sock_server); //關閉已連接套接字
WSACleanup(); //註銷WinSock動態鏈接庫
return 0;
}
// 開始監聽 [12/27/2017 MagicScaring]
if (listen(sock_server, 0) != 0)
{
cout << "listen調用失敗!錯誤代碼:" << WSAGetLastError() << endl;
closesocket(sock_server);
WSACleanup();
return 0;
}
else
{
cout << "listening...." << endl;
}
// 循環:接收連接請求並收發數據 [12/27/2017 MagicScaring]
int size;
while (true)
{
if ((newsock = accept(sock_server, (struct sockaddr *)&client_addr, &addr_len)) == INVALID_SOCKET)
{
cout << "accept 函數調用失敗! 錯誤代碼:" << WSAGetLastError() << endl;
break;
}
else
{
cout << "成功接收到一個連接請求!" << endl;
size = send(newsock, msg, sizeof(msg), 0);
if (size == SOCKET_ERROR)
{
cout << "發送信息失敗! 錯誤代碼:" << WSAGetLastError() << endl;
closesocket(newsock);
continue;
}
else if (size == 0)
{
cout << "對方已關閉連接" << endl;
closesocket(newsock);
continue;
}
else
{
cout << "信息發送成功" << endl;
}
size = recv(newsock, msg, sizeof(msg), 0);
if (size == SOCKET_ERROR)
{
cout << "接收信息失敗! 錯誤代碼:" << WSAGetLastError() << endl;
closesocket(newsock);
WSACleanup();
return 0;
}
else if (size == 0)
{
cout << "對方已關閉連接" << endl;
closesocket(newsock);
WSACleanup();
return 0;
}
else
{
cout << "The message from Client:" << msg << endl;
}
}
}
return 0;
}
客戶端程序代碼:
// Client.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib, "WS2_32.lib")
//表示鏈接WS2_32.lib這個庫。
#define PORT 1024
int main()
{
SOCKET sock_client;
struct sockaddr_in server_addr;
int addr_len = sizeof(struct sockaddr_in);
char msgbuffer[1000];
memset(msgbuffer, 0, sizeof(msgbuffer));
// 初始化 winsock2.dll[12/27/2017 MagicScaring]
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2); //生成版本號
if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
cout << "加載 winsock.dll失敗" << endl;
return 0;
}
// 創建套接字 [12/27/2017 MagicScaring]
if ((sock_client = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
{
cout << "創建套接字失敗! 錯誤代碼:" << WSAGetLastError() << endl;
WSACleanup(); //註銷WinSock動態鏈接庫
return 0;
}
// 填寫服務器地址 [12/27/2017 MagicScaring]
char IP[20] = { "192.168.5.38" };
/*char IP[20];
cout << "輸入服務器地址:" << endl;
cin >> IP;*/
memset((void*)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr(IP);
// 與服務器建立連接 [12/27/2017 MagicScaring]
if (connect(sock_client, (struct sockaddr*)&server_addr, addr_len) == SOCKET_ERROR)
{
cout << "連接失敗! 錯誤代碼:" << WSAGetLastError() << endl;
closesocket(sock_client);
WSACleanup();
return 0;
}
while (true)
{
int size;
if ((size = recv(sock_client, msgbuffer, sizeof(msgbuffer), 0)) == SOCKET_ERROR)
{
cout << "接收信息失敗! 錯誤代碼:" << WSAGetLastError() << endl;
closesocket(sock_client);
WSACleanup();
return 0;
}
else if (size == 0)
{
cout << "對方已關閉連接" << endl;
closesocket(sock_client);
WSACleanup();
return 0;
}
else
{
cout << "The message from Server:" << msgbuffer << endl;
}
char send_msg[1000] = { "Hello server" };
if((size = send(sock_client, send_msg, sizeof(send_msg),0)) == SOCKET_ERROR)
{
cout << "發送信息失敗! 錯誤代碼:" << WSAGetLastError() << endl;
}
else if (size == 0)
{
cout << "對方已關閉連接" << endl;
}
else
{
cout << "信息發送成功" << endl;
}
}
closesocket(sock_client);
WSACleanup();
return 0;
}
服務器程序運行結果:
客戶端程序運行結果: