Написал убогую программу чата на сокетах в С++. Отправка сообщений есть и работает, но когда выхожу из 1 клиента , на оставшихся бесконечно выводиться его последнее сообщение. Что делать? Я так думаю , что у меня не корректно закрыты сокеты , прошу помочь с этой проблемой.
Сервер
#include "stdafx.h" // ускорение компиляции .
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#pragma warning(disable: 4996)//убирает ошибку устаревших библеотек
SOCKET Connections[100];// массив сокетов подключения
int Counter = 0; // индекс соединения
void ClientHandler(int index) {
char msg[256];
while (true) {
recv(Connections[index], msg, sizeof(msg), NULL);
for (int i = 0; i < Counter; i++) {
send(Connections[i], msg, sizeof(msg), NULL);
}
}
}
int main(int argc, char* argv[]) {
setlocale(0, "Rus");
system("chcp 1251");
//WSAStartup < Инициализация библиотеки <winsock2.h> для работы с сокетами
WSAData wsaData;
WORD DLLVersion = MAKEWORD(2, 1);
if (WSAStartup(DLLVersion, &wsaData) != 0) {
std::cout << "Error" << std::endl;
exit(1);
}
SOCKADDR_IN addr; // структура адреса
int sizeofaddr = sizeof(addr);// размер адреса
addr.sin_addr.s_addr = inet_addr("127.0.0.1");// подлючение к 1 сети
addr.sin_port = htons(1111);//(сетевой порядок) преобразует узловой порядок расположения байтов в сетевой порядок
addr.sin_family = AF_INET; // подключение через итернет
SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);//создание сокета(слушать) для соединения
bind(sListen, (SOCKADDR*)&addr, sizeof(addr));// Связывает сокет с конкретным адресом
listen(sListen, SOMAXCONN);
SOCKET newConnection;
for (int i = 0; i < 100; i++) {
newConnection = accept(sListen, (SOCKADDR*)&addr, &sizeofaddr);// создание сокета для работы(только на сервере)
if (newConnection == 0) {
std::cout << "Error #2\n";
}
else {
char name_client[256];
recv(newConnection, name_client, sizeof(name_client), NULL);// считывает с сокета
std::cout << "Клиент " << name_client << " Подключился!\n";
Connections[i] = newConnection; // записываем соединение в массив
Counter++; // следующие соединение
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientHandler, (LPVOID)(i), NULL, NULL);
}
}
shutdown(sListen, 0);
shutdown(newConnection, 0);
closesocket(newConnection);
closesocket(sListen);
delete[100] Connections;
system("pause");
return 0;
}
Клиент
#include "stdafx.h"
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#pragma warning(disable: 4996)//убирает ошибку устаревших библеотек
SOCKET Connection;// массив сокетов подключения
void ClientHandler() {
char msg[256];
while (true) {
recv(Connection, msg, sizeof(msg), NULL);
std::cout << msg << std::endl;
}
}
int main(int argc, char* argv[]) {
//WSAStartup < Инициализация библиотеки <winsock2.h> для работы с сокетами
WSAData wsaData;
WORD DLLVersion = MAKEWORD(2, 1);
if (WSAStartup(DLLVersion, &wsaData) != 0) {
std::cout << "Error" << std::endl;
exit(1);
}
SOCKADDR_IN addr; // структура адреса
int sizeofaddr = sizeof(addr);// размер адреса
addr.sin_addr.s_addr = inet_addr("127.0.0.1");// подлючение к 1 сети
addr.sin_port = htons(1111);// (сетевой порядок) преобразует узловой порядок расположения байтов в сетевой порядок
addr.sin_family = AF_INET; // подключение через итернет
Connection = socket(AF_INET, SOCK_STREAM, NULL);
if (connect(Connection, (SOCKADDR*)&addr, sizeof(addr)) != 0) {
std::cout << "Error: failed connect to server.\n";
return 1;
}
std::cout << "Conected !\n";
char name_client[256];
std::cout << "Enter your online name\n";
std::cin.getline(name_client, 256);
send(Connection, name_client, sizeof(name_client), NULL);// записывает в сокет
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientHandler, NULL, NULL, NULL);
char msg1[256];
while (true) {
std::cin.getline(msg1, sizeof(msg1));
//strcat(name_client, msg1);
send(Connection, msg1, sizeof(msg1), NULL);
}
shutdown(Connection, 0);
closesocket(Connection);
system("pause");
return 0;
}