下面是大致的思路,具体细节及参数可查看相关函数
Server.cpp
#include <WinSock2.h>
#include <iostream>
//
#pragma comment(lib,"WS2_32.lib")
#define BUF_SIZE 64
int main()
{
// 用于初始化socket
WSADATA wsd;
// 服务器socket监听客户端请求
SOCKET sServer;
// 客户端socket,用于实现与客户端的连接
SOCKET sClient;
// 调用各种socket函数的返回值
int retVal;
char buf[BUF_SIZE];
// 调用WSAStartup()函数,对socket环境进行初始化
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed !\n");
return 1;
}
// 初始化后,调用socket函数创建用于监听的socket
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sServer)
{
printf("socket failed!\n");
// 由于已经初始化了,需要调用WSACleanup函数进行清理
WSACleanup();
return -1;
}
// 设置服务器socket的监听地址,之后将socket与改地址进行绑定
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(9990);
addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
// 将监听socket与要监听的地址进行绑定
retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == retVal)
{
printf("bind failed!\n");
// 由于已经创建了socket,需要调用closesocket进行关闭并释放相应资源
closesocket(sServer);
WSACleanup();
return -1;
}
// 绑定地址后就可以调用listen函数进行监听
retVal = listen(sServer, 1);
if (SOCKET_ERROR == retVal)
{
printf("listen failed!\n");
closesocket(sServer);
WSACleanup();
return -1;
}
// 调用accept函数接收客户端的连接请求
printf("TCP Server start...\n");
// 获取客户端地址
sockaddr_in addrClient;
int addrClientLen = sizeof(addrClient);
// 创建sClient
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sClient)
{
printf("socket failed!\n");
// 由于已经初始化了,需要调用WSACleanup函数进行清理
WSACleanup();
return -1;
}
// 用sClient接收客户端请求并处理
sClient = accept(sClient, (sockaddr FAR*)&addrClient, &addrClientLen);
if (INVALID_SOCKET == sClient)
{
printf("accept failed!\n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
// 接收数据
while (true)
{
// 清空接收缓冲区
ZeroMemory(buf,BUF_SIZE);
retVal = recv(sClient, buf, BUF_SIZE, 0);
if (SOCKET_ERROR == retVal)
{
printf("recv failed!\n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
SYSTEMTIME st;
GetLocalTime(&st);
char sDateTime[30];
sprintf(sDateTime, "%4d-%2d-%2d:%2d-%2d-%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
printf("%s,Recv From Client[%s:%d]:%s\n", sDateTime, inet_ntoa(addrClient.sin_addr), addrClient.sin_port, buf);
//发送数据 如果收到客户端发送“quit”,则服务器退出
if (strcmp(buf, "quit") == 0)
{
retVal = send(sClient, "quit", strlen("quit"), 0);
break;
}
// 否则向客户端发送回显字符串
else
{
char msg[BUF_SIZE];
sprintf(msg, "Message received - %s", buf);
retVal = send(sClient, msg, strlen(msg), 0);
if (SOCKET_ERROR == retVal)
{
printf("send failed!\n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
}
}
// 释放资源
closesocket(sServer);
closesocket(sClient);
WSACleanup();
system("pause");
return 0;
}
Client.cpp
#include <WinSock2.h>
#include <string>
#include <iostream>
#pragma comment(lib,"WS2_32.lib")
#define BUF_SIZE 64
int main()
{
// 用于初始化socket
WSADATA wsd;
// 服务器socket监听客户端请求
SOCKET sHost;
// 服务器地址
SOCKADDR_IN servAddr;
// 调用各种socket函数的返回值
int retVal;
// 接收数据缓冲区
char buf[BUF_SIZE];
// 调用WSAStartup()函数,对socket环境进行初始化
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed !\n");
return 1;
}
// 创建用于通信的socket
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sHost)
{
printf("socket failed!\n");
// 由于已经初始化了,需要调用WSACleanup函数进行清理
WSACleanup();
return -1;
}
// 设置要连接的服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons(9990);
int sServerAddlen = sizeof(servAddr);
// 调用connect函数连接到服务器
retVal = connect(sHost, (LPSOCKADDR)&servAddr, sServerAddlen);
if (SOCKET_ERROR == retVal)
{
printf("connect failed!\n");
// 由于已经创建了socket,需要调用closesocket进行关闭并释放相应资源
closesocket(sHost);
WSACleanup();
return -1;
}
// 接收数据
while (true)
{
printf("please send a string to send:");
std::string str;
// 接收输入的数据
std:getline(std::cin, str);
ZeroMemory(buf, BUF_SIZE);
strcpy(buf, str.c_str());
// 向服务器发送数据
retVal = send(sHost, buf, strlen(buf), 0);
if (SOCKET_ERROR == retVal)
{
printf("send failed!\n");
closesocket(sHost);
WSACleanup();
return -1;
}
// 接收数据
retVal = recv(sHost, buf, sizeof(buf)+1, 0);
printf("rec from server:%s\n", buf);
// 如果收到quit就退出
if (strcmp(buf, "quit") == 0)
{
printf("quit\n");
break;
}
}
// 释放资源
closesocket(sHost);
WSACleanup();
system("pause");
return 0;
}