参考文章:
1.Windows Socket编程
2.揭开Socket编程的面纱
Windows下Socket TCP编程的大体流程如下:
Server端
1、初始化Windows Socket库.
2、创建Socket.
3、绑定Socket.
4、监听.
5、Accept.
6、接发数据.
Client端
1、初始化Windows Socket库.
2、创建Socket.
3、连接.
4、接发数据.
以下示例中,服务端接受客户端连接,并创建线程接收数据并输出。
客户端连接服务端,并向服务器端发送数据。
即非常简单的:Client端向Server端发送数据,Server端为每个Client端连接创建一个线程以接收数据并输出,连接结束则结束对应线程。
Server.cpp
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
#define PORT_NO 6000
#define BACKLOG 10
unsigned __stdcall clientThrd(void *lpParam)
{
SOCKET sockClient = (SOCKET)lpParam;
int ret = 0;
char recvBuffer[MAX_PATH] = {0};
// 接收数据------
while (1)
{
memset(recvBuffer, 0, sizeof(recvBuffer));
ret = recv(sockClient, recvBuffer, sizeof(recvBuffer), 0);
if (ret == 0)
{
cout << "Connection has been gracefully closed." << endl;
break;
}
else if (ret == SOCKET_ERROR)
{
cout << "Connection has been closed ungracefully." << endl;
break;
}
cout << "Receive Data from Client:" << recvBuffer << endl;
}
closesocket(sockClient);
return 0;
}
int main(int argc, char* argv[])
{
WSADATA wsaData;
int ret;
WORD wVersionRequested = MAKEWORD(2, 2);
SOCKET sockSrv, sockConn;
SOCKADDR_IN addrSrv, addrClient;
HANDLE hThread = NULL;
// 初始化Windows Socket------
ret = WSAStartup(wVersionRequested, &wsaData);
if (ret != 0)
{
cout << "WSAStartup() failed:" << WSAGetLastError() << endl;
return -1;
}
// 创建Socket------
sockSrv = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == sockSrv)
{
cout << "socket() failed:" << WSAGetLastError() << endl;
WSACleanup();
return -1;
}
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(PORT_NO);
// Bind Socket------
ret = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
if (SOCKET_ERROR == ret)
{
cout << "bind() failed:" << WSAGetLastError() << endl;
closesocket(sockSrv);
WSACleanup();
return -1;
}
// 监听------
ret = listen(sockSrv, BACKLOG);
if (SOCKET_ERROR == ret)
{
cout << "listen() failed:" << WSAGetLastError() << endl;
closesocket(sockSrv);
WSACleanup();
return -1;
}
cout<< "Server started......" << endl;
// Accept------
int len=sizeof(SOCKADDR);
while(1)
{
sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
if (INVALID_SOCKET == sockConn)
{
cout << "accept() failed:" << WSAGetLastError() << endl;
break;
}
hThread = (HANDLE)_beginthreadex(NULL, 0, clientThrd, (void*)sockConn, 0, NULL);
if (hThread == 0)
{
cout << "_beginthreadex() failed." << endl;
break;
}
CloseHandle(hThread);
}
// 清理资源------
closesocket(sockSrv);
WSACleanup();
cout << "exit..." << endl;
return 0;
}
Client.cpp
#include <iostream>
#include <windows.h>
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
#define PORT_NO 6000
#define SRV_IP_ADDR "127.0.0.1"
int main(int argc, char* argv[])
{
int ret;
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2);
SOCKET sockClient;
SOCKADDR_IN addrSrv;
// 初始化Windows Socket------
ret = WSAStartup(wVersionRequested, &wsaData);
if (ret != 0)
{
cout << "WSAStartup() failed:" << WSAGetLastError() << endl;
return -1;
}
// 创建Socket------
sockClient = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == sockClient)
{
cout << "socket() failed:" << WSAGetLastError() << endl;
WSACleanup();
return -1;
}
addrSrv.sin_addr.S_un.S_addr = inet_addr(SRV_IP_ADDR);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(PORT_NO);
// 连接------
ret = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
if (SOCKET_ERROR == ret)
{
cout << "connect() failed:" << WSAGetLastError() << endl;
closesocket(sockClient);
WSACleanup();
return -1;
}
else
{
cout << "connect() successfully." << endl;
}
// 发送数据------
char sendBuf[MAX_PATH] = {0};
while (1)
{
cin.getline(sendBuf, sizeof(sendBuf));
if (strcmp(sendBuf, "exit") == 0)
{
break;
}
ret = send(sockClient, sendBuf, strlen(sendBuf)+1, 0);
if (SOCKET_ERROR == ret)
{
cout << "send() failed:" << WSAGetLastError() << endl;
closesocket(sockClient);
WSACleanup();
return -1;
}
}
// 清理资源-------
closesocket(sockClient);
WSACleanup();
cout << "exit..." << endl;
return 0;
}