Windows下实现 C/C++下TCP, 服务器/客户端 "多人聊天室",客户端用户需要登陆,用户账号密码用txt保存并读取
时间: 2023-06-18 22:07:07 浏览: 55
下面是一个简单的 C++ 实现,用于实现 Windows 下的 TCP 服务器/客户端多人聊天室,包括客户端用户的登录和账号密码的读取。
### 服务器端
```cpp
#include <iostream>
#include <winsock2.h>
#include <windows.h>
#include <vector>
#include <fstream>
#include <sstream>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
struct User {
string name;
string password;
};
vector<User> users;
void LoadUsers() {
ifstream file("users.txt");
string line;
while (getline(file, line)) {
stringstream ss(line);
string name, password;
ss >> name >> password;
users.push_back({name, password});
}
}
bool CheckUser(string name, string password) {
for (auto user : users) {
if (user.name == name && user.password == password) {
return true;
}
}
return false;
}
int main() {
LoadUsers();
WSADATA wsaData;
SOCKET serverSocket, clientSocket;
SOCKADDR_IN serverAddr, clientAddr;
int port = 12345;
char buffer[1024];
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
cout << "WSAStartup failed!" << endl;
return 1;
}
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
cout << "Create socket failed!" << endl;
return 1;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
serverAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
cout << "Bind socket failed!" << endl;
closesocket(serverSocket);
return 1;
}
listen(serverSocket, SOMAXCONN);
cout << "Server started!" << endl;
while (true) {
int clientAddrLen = sizeof(clientAddr);
clientSocket = accept(serverSocket, (SOCKADDR*)&clientAddr, &clientAddrLen);
if (clientSocket == INVALID_SOCKET) {
cout << "Accept failed!" << endl;
closesocket(serverSocket);
return 1;
}
cout << "Client connected: " << inet_ntoa(clientAddr.sin_addr) << ":" << ntohs(clientAddr.sin_port) << endl;
while (true) {
int result = recv(clientSocket, buffer, sizeof(buffer), 0);
if (result == SOCKET_ERROR || result == 0) {
cout << "Client disconnected: " << inet_ntoa(clientAddr.sin_addr) << ":" << ntohs(clientAddr.sin_port) << endl;
closesocket(clientSocket);
break;
}
string message(buffer, result);
if (message.find("login") == 0) {
stringstream ss(message.substr(6));
string name, password;
ss >> name >> password;
if (CheckUser(name, password)) {
string response = "Login success!";
send(clientSocket, response.c_str(), response.size() + 1, 0);
} else {
string response = "Login failed!";
send(clientSocket, response.c_str(), response.size() + 1, 0);
}
} else {
cout << message << endl;
for (SOCKET i = 0; i < SOMAXCONN; i++) {
if (i != serverSocket && i != clientSocket) {
send(i, message.c_str(), message.size() + 1, 0);
}
}
}
}
}
closesocket(serverSocket);
WSACleanup();
return 0;
}
```
### 客户端
```cpp
#include <iostream>
#include <winsock2.h>
#include <windows.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
int main() {
WSADATA wsaData;
SOCKET clientSocket;
SOCKADDR_IN serverAddr;
int port = 12345;
char buffer[1024];
string username, password;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
cout << "WSAStartup failed!" << endl;
return 1;
}
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
cout << "Create socket failed!" << endl;
return 1;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
cout << "Connect failed!" << endl;
closesocket(clientSocket);
return 1;
}
cout << "Enter your username: ";
getline(cin, username);
cout << "Enter your password: ";
getline(cin, password);
string loginMessage = "login " + username + " " + password;
send(clientSocket, loginMessage.c_str(), loginMessage.size() + 1, 0);
while (true) {
string message;
getline(cin, message);
message = username + ": " + message;
send(clientSocket, message.c_str(), message.size() + 1, 0);
}
closesocket(clientSocket);
WSACleanup();
return 0;
}
```
以上代码仅作为示例,实际场景中可能有更复杂的需求。在实际应用中,还需要考虑网络安全等问题。