下面是一个简单的C++聊天程序,可以实现客户端和服务器的通信:
// Client.cpp
#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
int main()
{
std::string ipAddress = "127.0.0.1"; // IP地址
int port = 54000; // 端口号
// 初始化Winsock
WSADATA data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
if (wsOk != 0)
{
std::cerr << "Can't initialize Winsock! Quitting" << std::endl;
return -1;
}
// 创建socket
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
std::cerr << "Can't create socket! Quitting" << std::endl;
return -1;
}
// 连接服务器
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
hint.sin_addr.s_addr = inet_addr(ipAddress.c_str());
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR)
{
std::cerr << "Can't connect to server! Error #" << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return -1;
}
// 循环等待消息
char buf[4096];
std::string userInput;
do {
// 提示用户输入消息
std::cout << "> ";
std::getline(std::cin, userInput);
if (userInput.size() > 0) // 确保用户输入了消息
{
// 发送消息给服务器
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult != SOCKET_ERROR)
{
// 等待响应
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0)
{
// 将服务器响应输出到控制台
std::cout << "SERVER> " << std::string(buf, 0, bytesReceived) << std::endl;
}
}
}
} while (userInput.size() > 0);
// 清理
closesocket(sock);
WSACleanup();
return 0;
}
// Server.cpp
#include
#include
#include
#pragma comment (lib, "ws2_32.lib")
int main()
{
std::string ipAddress = "127.0.0.1"; // IP地址
int port = 54000; // 端口号
// 初始化Winsock
WSADATA data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
if (wsOk != 0)
{
std::cerr << "Can't initialize Winsock! Quitting" << std::endl;
return -1;
}
// 创建socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
std::cerr << "Can't create socket! Quitting" << std::endl;
return -1;
}
// 将socket绑定到IP地址和端口号上
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
hint.sin_addr.s_addr = inet_addr(ipAddress.c_str());
bind(listening, (sockaddr*)&hint, sizeof(hint));
// 开始监听socket
listen(listening, SOMAXCONN);
// 等待连接
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
char host[NI_MAXHOST]; // 主机名
char service[NI_MAXSERV]; // 服务名
ZeroMemory(host, NI_MAXHOST); // 将缓冲区清空
ZeroMemory(service, NI_MAXSERV);
// 获取主机名和服务名
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
std::cout << host << " connected on port " << service << std::endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
std::cout << host << " connected on port " << ntohs(client.sin_port) << std::endl;
}
// 关闭监听socket
closesocket(listening);
// 循环等待消息
char buf[4096];
while (true)
{
ZeroMemory(buf, 4096);
// 等待客户端消息
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR)
{
std::cerr << "Error in recv(). Quitting" << std::endl;
break;
}
if (bytesReceived == 0)
{
std::cout << "Client disconnected" << std::endl;
break;
}
// 将收到的消息输出到控制台
std::cout << std::string(buf, 0, bytesReceived) << std::endl;
// 将消息回发给客户端
send(clientSocket, buf, bytesReceived + 1, 0);
}
// 关闭socket
closesocket(clientSocket);
// 清理
WSACleanup();
return 0;
}