1 建立能够持续请求的CS网络程序
1.1 概述
我们在上一次的代码基础,建立能够持续请求的CS网络程序:
用Socket API建立简易TCP服务端:
- 建立一个socket
- 绑定接受客户端连接的端口 bind
- 监听网络端口 listen
- 等待新客户端连接 accept
- 等待客户端请求 recv
- 向客户端返回请求的数据send
//–循环5-6 - 关闭socket closesocket
用Socket API建立简易TCP客户端
- 建立一个socket
- 连接服务器 connect
- 向服务端发送请求 send
- 接收服务器返回的数据 recv
//–循环3-4 - 关闭socket closesocket
1.2 服务端代码
server.cpp:
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main()
{
WSADATA data;
WORD version = MAKEWORD(2, 2);
// 初始化Sokcet库
WSAStartup(version, &data);
//-- 用Socket API建立简易TCP服务端
// 1 建立一个socket
SOCKET _sock;
_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == _sock)
{
cout << "server : create socket error !" << endl;
WSACleanup();
return -1;
}
else
{
cout << "server : create socket success !" << endl;
}
// 2 bind 绑定用于接受客户端连接的网络端口
sockaddr_in _sockaddr;
_sockaddr.sin_family = AF_INET;
_sockaddr.sin_port = htons(4567);
_sockaddr.sin_addr.S_un.S_addr = ADDR_ANY; //inet_addr("127.0.0.1");
int ret = bind(_sock, (sockaddr*)&_sockaddr, sizeof(sockaddr_in));
if (SOCKET_ERROR == ret)
{
cout << "server : bind error!" << endl;
WSACleanup();
return -1;
}
else
{
cout << "server : bind success !" << endl;
}
// 3 listen 监听网络端口
ret = listen(_sock, 5);
if (SOCKET_ERROR == ret)
{
cout << "server : listen error !" << endl;
WSACleanup();
return -1;
}
else
{
cout << "server : listen success !" << endl;
}
sockaddr_in _sockaddr_in;
int len = sizeof(sockaddr_in);
// 4 accept 等待接受客户端连接
SOCKET clientSock = accept(_sock, (sockaddr*)&_sockaddr_in, &len);
if (INVALID_SOCKET == clientSock)
{
cout << "server : accept bad socket!" << endl;
}
else
{
cout << "server : new client join, IP : " << inet_ntoa(_sockaddr_in.sin_addr) << endl;
}
char buffer[] = "hello, client! I am server !";
while (true)
{
// 5 从客户端接收数据并处理
int recvLen = recv(clientSock, buffer, sizeof(buffer), 0);
if (recvLen > 0)
{
cout << "recv : " << buffer << endl;
if (0 == strcmp(buffer, "getName"))
{
char msgBuffer[] = "lemon";
send(clientSock, msgBuffer, strlen(msgBuffer) + 1, 0);
}
else if (0 == strcmp(buffer, "getAge"))
{
char msgBuffer[] = "18";
send(clientSock, msgBuffer, strlen(msgBuffer) + 1, 0);
}
else
{
char msgBuffer[] = "??? What are you want to ask?";
send(clientSock, msgBuffer, strlen(msgBuffer) + 1, 0);
}
}
else
{
cout << "client quit ..." << endl;
break;
}
}
// 6 关闭套节字closesocket
closesocket(_sock);
// 对Socket资源进行处理
WSACleanup();
getchar();
return 0;
}
1.3 客户端代码
client.cpp:
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main()
{
WSADATA data;
WORD version = MAKEWORD(2, 2);
// 初始化Sokcet库
WSAStartup(version, &data);
//------------
//-- 用Socket API建立简易TCP客户端
// 1 建立一个socket
SOCKET _sock;
_sock = socket(AF_INET, SOCK_STREAM, 0); // 客户端的协议类型可以直接给0
if (INVALID_SOCKET == _sock)
{
cout << "client : create socket error !" << endl;
WSACleanup();
return -1;
}
else
{
cout << "client : create socket success !" << endl;
}
// 2 连接服务器 connect
sockaddr_in _sockaddr;
_sockaddr.sin_family = AF_INET;
_sockaddr.sin_port = htons(4567);
_sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int ret = connect(_sock, (sockaddr*)&_sockaddr, sizeof(sockaddr_in));
if (SOCKET_ERROR == ret)
{
cout << "client : connect error !" << endl;
WSACleanup();
return -1;
}
else
{
cout << "client : connect success !" << endl;
}
char cmdBuffer[128] = { 0 };
char recvBuffer[128] = { 0 };
while (true)
{
// 3 接收用户输入并发送到服务器,然后接收回应
cin >> cmdBuffer;
if (0 == strcmp(cmdBuffer, "quit"))
{
break;
}
send(_sock, cmdBuffer, strlen(cmdBuffer) + 1, 0);
int len = recv(_sock, recvBuffer, sizeof(recvBuffer), 0);
if (len > 0)
{
cout << "client recv : " << recvBuffer << endl;
}
else
{
break;
}
}
// 4 关闭套节字closesocket
closesocket(_sock);
// 对Socket资源进行处理
WSACleanup();
getchar();
return 0;
}
参考资料: