Вы неправильно используете strlen()
внутри своего кода потока.
При вызове recv()
вам необходимо указать полный размер буфера.strlen()
- неправильный способ получить это значение.Вместо этого используйте sizeof()
.
Затем, когда выйдет recv()
, его возвращаемое значение точно скажет, сколько байтов в буфере допустимо.Опять же, strlen()
- неправильный способ получить это значение.
Кроме того, вам не нужно завершать буфер нулем, просто чтобы передать его в send()
.Поскольку вам сообщают, сколько байтов находится в буфере, просто отправьте это количество байтов.
Кроме того, ваши потоки не завершают работу и не закрывают свои сокеты, когда клиенты отключаются от сервера.
Кроме того, у вашего main()
есть утечка дескрипторов потоков, и он вообще не выполняет никакой обработки ошибок.
Вместо этого попробуйте что-то вроде этого:
bool sendAll(SOCKET sock, void *buf, int buflen)
{
char *ptr = (char*) buf;
int sent;
while (buflen > 0) {
sent = send(sock, ptr, buflen, 0);
if (sent == SOCKET_ERROR) {
return false;
}
ptr += sent;
buflen -= sent;
}
return true;
}
DWORD WINAPI process_thread(LPVOID lpParam) {
SOCKET client = (SOCKET) lpParam;
char buf[1024], *ptr;
int recvd;
do {
recvd = recv(client, buf, sizeof(buf), 0);
if (recvd <= 0) {
break;
}
if (!sendAll(client, buf, recvd)) {
break;
}
}
while (true);
closesocket(client);
return 0;
}
int main() {
WSADATA wsaData;
SOCKET server, client;
SOCKADDR_IN serveraddr;
SOCKADDR_IN clientaddr;
int res, clientaddrlen;
HANDLE hThread;
DWORD threadID;
res = WSAStartup(MAKEWORD(2, 1), &wsaData);
if (res != 0) {
return 1;
}
ZeroMemory(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = INADDR_ANY;
serveraddr.sin_port = htons(123);
server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server == INVALID_SOCKET) {
WSACleanup();
return 1;
}
res = bind(server, (SOCKADDR*) &serveraddr, sizeof(serveraddr));
if (res == SOCKET_ERROR) {
closesocket(server);
WSACleanup();
return 1;
}
res = listen(server, 5);
if (res == SOCKET_ERROR) {
closesocket(server);
WSACleanup();
return 1;
}
do {
clientaddrlen = sizeof(clientaddr);
client = accept(server, (SOCKADDR*) &clientaddr, &clientaddrlen);
if (client == INVALID_SOCKET) {
closesocket(server);
WSACleanup();
return 1;
}
hThread = CreateThread(NULL, 0, process_thread, (LPVOID) client, 0, &threadID);
if (hThread)
CloseHandle(hThread);
else
closesocket(client);
}
while (true);
closesocket(server);
WSACleanup();
return 0;
}