帮我用c++写windows下基于socket通信的聊天室服务器与客户端实现的代码 完成功能: 1.用户注册功能; 2.两个用户服务器发送私密消息; 3.用户创建一个或多个聊天群组; 4.用户加入群组、在群组内发送消息、离开群组; 5.用户之间的聊天信息通过服务器端转发;
时间: 2024-05-10 09:15:22 浏览: 118
c++实现Socket服务器和客户端功能
以下是基于socket通信的聊天室服务器与客户端的代码,实现了您所要求的功能:
服务器端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define MAX_CLIENTS 30
#define MAX_GROUPS 5
#define MAX_GROUP_SIZE 10
#define MAX_USERNAME_LENGTH 20
#define MAX_MESSAGE_LENGTH 100
typedef struct {
char username[MAX_USERNAME_LENGTH];
SOCKET socket;
int in_group;
int group_id;
} client;
typedef struct {
char name[MAX_USERNAME_LENGTH];
int clients[MAX_GROUP_SIZE];
int num_clients;
} group;
client clients[MAX_CLIENTS];
group groups[MAX_GROUPS];
int num_clients = 0;
int num_groups = 0;
void send_message_to_all(char* message, int sender_id) {
int i;
for (i = 0; i < num_clients; i++) {
if (i != sender_id) {
send(clients[i].socket, message, strlen(message), 0);
}
}
}
void send_message_to_group(char* message, int sender_id, int group_id) {
int i;
for (i = 0; i < groups[group_id].num_clients; i++) {
int client_id = groups[group_id].clients[i];
if (client_id != sender_id) {
send(clients[client_id].socket, message, strlen(message), 0);
}
}
}
void add_client_to_group(int client_id, int group_id) {
clients[client_id].in_group = 1;
clients[client_id].group_id = group_id;
groups[group_id].clients[groups[group_id].num_clients] = client_id;
groups[group_id].num_clients++;
}
void remove_client_from_group(int client_id) {
int group_id = clients[client_id].group_id;
int i;
for (i = 0; i < groups[group_id].num_clients; i++) {
if (groups[group_id].clients[i] == client_id) {
groups[group_id].num_clients--;
groups[group_id].clients[i] = groups[group_id].clients[groups[group_id].num_clients];
break;
}
}
clients[client_id].in_group = 0;
clients[client_id].group_id = -1;
}
void handle_client_message(int client_id, char* message) {
if (strncmp(message, "/register ", 10) == 0) {
char* username = message + 10;
strncpy(clients[client_id].username, username, MAX_USERNAME_LENGTH);
printf("Client %d registered as %s\n", client_id, clients[client_id].username);
send(clients[client_id].socket, "Registered successfully.\n", 25, 0);
} else if (strncmp(message, "/private ", 9) == 0) {
char* recipient_username = message + 9;
char* message_text = strchr(recipient_username, ' ');
if (message_text == NULL) {
send(clients[client_id].socket, "Invalid command.\n", 17, 0);
return;
}
*message_text = '\0';
message_text++;
int i;
int recipient_id = -1;
for (i = 0; i < num_clients; i++) {
if (strcmp(clients[i].username, recipient_username) == 0) {
recipient_id = i;
break;
}
}
if (recipient_id == -1) {
send(clients[client_id].socket, "Recipient not found.\n", 22, 0);
return;
}
char full_message[MAX_MESSAGE_LENGTH + MAX_USERNAME_LENGTH + 4];
sprintf(full_message, "(private from %s): %s\n", clients[client_id].username, message_text);
send(clients[recipient_id].socket, full_message, strlen(full_message), 0);
send(clients[client_id].socket, "Message sent.\n", 15, 0);
} else if (strncmp(message, "/create_group ", 14) == 0) {
char* group_name = message + 14;
if (num_groups >= MAX_GROUPS) {
send(clients[client_id].socket, "Maximum number of groups reached.\n", 34, 0);
return;
}
strncpy(groups[num_groups].name, group_name, MAX_USERNAME_LENGTH);
groups[num_groups].num_clients = 0;
send(clients[client_id].socket, "Group created.\n", 16, 0);
add_client_to_group(client_id, num_groups);
num_groups++;
} else if (strncmp(message, "/join_group ", 12) == 0) {
char* group_name = message + 12;
int i;
int group_id = -1;
for (i = 0; i < num_groups; i++) {
if (strcmp(groups[i].name, group_name) == 0) {
group_id = i;
break;
}
}
if (group_id == -1) {
send(clients[client_id].socket, "Group not found.\n", 18, 0);
return;
}
if (groups[group_id].num_clients >= MAX_GROUP_SIZE) {
send(clients[client_id].socket, "Group is full.\n", 16, 0);
return;
}
add_client_to_group(client_id, group_id);
send(clients[client_id].socket, "Group joined.\n", 15, 0);
} else if (strncmp(message, "/leave_group", 12) == 0) {
if (!clients[client_id].in_group) {
send(clients[client_id].socket, "You are not in a group.\n", 24, 0);
return;
}
remove_client_from_group(client_id);
send(clients[client_id].socket, "Group left.\n", 13, 0);
} else {
if (clients[client_id].in_group) {
char full_message[MAX_MESSAGE_LENGTH + MAX_USERNAME_LENGTH + 4];
sprintf(full_message, "(%s): %s\n", clients[client_id].username, message);
send_message_to_group(full_message, client_id, clients[client_id].group_id);
} else {
char full_message[MAX_MESSAGE_LENGTH + MAX_USERNAME_LENGTH + 4];
sprintf(full_message, "(%s): %s\n", clients[client_id].username, message);
send_message_to_all(full_message, client_id);
}
}
}
int main(int argc, char* argv[]) {
WSADATA wsa;
SOCKET master_socket, new_socket;
struct sockaddr_in server, address;
int addrlen = sizeof(address);
char message[MAX_MESSAGE_LENGTH];
int opt = 1;
int i;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a master socket
if ((master_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket : %d", WSAGetLastError());
}
//Set master socket to allow multiple connections
if (setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0) {
printf("setsockopt");
}
//Bind the socket to localhost port 8888
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if (bind(master_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed with error code : %d", WSAGetLastError());
}
//Listen for incoming connections
listen(master_socket, 3);
//Accept incoming connections
puts("Waiting for connections...");
while (1) {
new_socket = accept(master_socket, (struct sockaddr*)&address, &addrlen);
if (new_socket == INVALID_SOCKET) {
printf("accept failed with error code : %d", WSAGetLastError());
continue;
}
printf("New connection from %s:%d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));
//Add new client to array
clients[num_clients].socket = new_socket;
clients[num_clients].in_group = 0;
clients[num_clients].group_id = -1;
num_clients++;
//Send welcome message to client
send(new_socket, "Welcome to the chat server.\n", 28, 0);
//Receive message from client
while (1) {
int num_bytes = recv(new_socket, message, MAX_MESSAGE_LENGTH, 0);
if (num_bytes == SOCKET_ERROR) {
printf("recv failed with error code : %d", WSAGetLastError());
break;
}
if (num_bytes == 0) {
printf("Connection closed by client.\n");
break;
}
message[num_bytes] = '\0';
printf("Received message from client %d: %s\n", num_clients - 1, message);
handle_client_message(num_clients - 1, message);
}
//Remove client from array
int client_id = num_clients - 1;
closesocket(clients[client_id].socket);
if (clients[client_id].in_group) {
remove_client_from_group(client_id);
}
num_clients--;
}
closesocket(master_socket);
WSACleanup();
return 0;
}
```
客户端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define MAX_MESSAGE_LENGTH 100
int main(int argc, char* argv[]) {
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
char message[MAX_MESSAGE_LENGTH];
char server_reply[MAX_MESSAGE_LENGTH];
int i;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket : %d", WSAGetLastError());
}
//Connect to remote server
server.sin_addr.s_addr = inet_addr("127.0.0.1"); //localhost
server.sin_family = AF_INET;
server.sin_port = htons(8888);
if (connect(s, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("connect failed. Error");
return 1;
}
//Receive welcome message from server
if (recv(s, server_reply, MAX_MESSAGE_LENGTH, 0) < 0) {
printf("recv failed with error code : %d", WSAGetLastError());
}
printf("%s", server_reply);
//Register with server
printf("Enter username: ");
fgets(message, MAX_MESSAGE_LENGTH, stdin);
message[strlen(message) - 1] = '\0'; //remove newline character
sprintf(server_reply, "/register %s", message);
if (send(s, server_reply, strlen(server_reply), 0) < 0) {
printf("send failed with error code : %d", WSAGetLastError());
}
if (recv(s, server_reply, MAX_MESSAGE_LENGTH, 0) < 0) {
printf("recv failed with error code : %d", WSAGetLastError());
}
printf("%s", server_reply);
//Enter main loop
while (1) {
printf("Enter message: ");
fgets(message, MAX_MESSAGE_LENGTH, stdin);
message[strlen(message) - 1] = '\0'; //remove newline character
if (strncmp(message, "/private ", 9) == 0) {
if (send(s, message, strlen(message), 0) < 0) {
printf("send failed with error code : %d", WSAGetLastError());
}
if (recv(s, server_reply, MAX_MESSAGE_LENGTH, 0) < 0) {
printf("recv failed with error code : %d", WSAGetLastError());
}
printf("%s", server_reply);
} else if (strncmp(message, "/create_group ", 14) == 0) {
if (send(s, message, strlen(message), 0) < 0) {
printf("send failed with error code : %d", WSAGetLastError());
}
if (recv(s, server_reply, MAX_MESSAGE_LENGTH, 0) < 0) {
printf("recv failed with error code : %d", WSAGetLastError());
}
printf("%s", server_reply);
} else if (strncmp(message, "/join_group ", 12) == 0) {
if (send(s, message, strlen(message), 0) < 0) {
printf("send failed with error code : %d", WSAGetLastError());
}
if (recv(s, server_reply, MAX_MESSAGE_LENGTH, 0) < 0) {
printf("recv failed with error code : %d", WSAGetLastError());
}
printf("%s", server_reply);
} else if (strncmp(message, "/leave_group", 12) == 0) {
if (send(s, message, strlen(message), 0) < 0) {
printf("send failed with error code : %d", WSAGetLastError());
}
if (recv(s, server_reply, MAX_MESSAGE_LENGTH, 0) < 0) {
printf("recv failed with error code : %d", WSAGetLastError());
}
printf("%s", server_reply);
} else {
if (send(s, message, strlen(message), 0) < 0) {
printf("send failed with error code : %d", WSAGetLastError());
}
}
}
closesocket(s);
WSACleanup();
return 0;
}
```
阅读全文