首页 > 解决方案 > 我正在使用 Windows 10 和 C (visual studio 2015) 编写聊天程序

问题描述

我正在使用 Windows 10 和 C (Visual Studio 2015) 编写多客户端聊天程序。

当我执行两个客户端文件时。似乎它工作正常,但是在我终止第一个客户端文件并重新执行它之后,两个客户端之一无法接收来自服务器的消息。

我不知道它有什么问题。。

以下是我的代码、服务器和客户端。

//server
#include <stdio.h>
#include <Windows.h>

unsigned WINAPI client_management(void *arg);
void sending_message(char *message, int length_of_message);

int counting_clients = 0;
SOCKET socket_of_clients[1024];
HANDLE hMutex;

int main(int argc, char *argv[]) {

    WSADATA wsaData;

    HANDLE client_management_thread;

    struct sockaddr_in address_of_server;
    struct sockaddr_in address_of_client;

    int size_of_address_of_client = sizeof(address_of_client);

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) == -1) {
        printf("failed\n\n");
    }

    hMutex = CreateMutex(NULL, FALSE, NULL);

    SOCKET socket_of_server = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_of_server == -1) {
        printf("failed\n\n");
    }

    SOCKET socket_of_client;

    memset(&address_of_server, 0, sizeof(address_of_server));
    address_of_server.sin_family = AF_INET;
    address_of_server.sin_addr.s_addr = htonl(INADDR_ANY);
    address_of_server.sin_port = htons(atoi("10000"));

    if (bind(socket_of_server, (struct sockaddr*)&address_of_server,                sizeof(address_of_server)) == -1) {
        printf("failed\n\n");
    }

    if (listen(socket_of_server, 5) == -1) {
        printf("failed\n\n");
    }

    printf("waiting\n\n");

    while (1) {
        socket_of_client = accept(socket_of_server, (struct sockaddr*)&address_of_client, &size_of_address_of_client);
        if (socket_of_client != -1) {
            printf("connected\n\n");
        }
        WaitForSingleObject(hMutex, INFINITE);
        socket_of_clients[counting_clients] = socket_of_client;
        ReleaseMutex(hMutex);
        client_management_thread = (HANDLE)_beginthreadex(NULL, 0, client_management, (void*)&socket_of_client, 0, NULL);
        counting_clients++;
        printf("client: %d\n\n", counting_clients);
    }
    closesocket(socket_of_server);
    WSACleanup();
}

unsigned WINAPI client_management(void *arg) {
SOCKET socket_of_client = *((SOCKET*)arg);
int strLen = 0, i;
char message[1024];

while ((strLen = recv(socket_of_client, message, 1024, 0)) != -1) {
    printf("arrived message: %s\n\n", message);
    sending_message(message, 1024);
}

WaitForSingleObject(hMutex, INFINITE);

for (i = 0; i < counting_clients; i++) {
    if (socket_of_client == socket_of_clients[i]) {
        while (i++ < counting_clients - 1) {
            socket_of_clients[i] = socket_of_clients[i + 1];
            break;
        }
    }
}
counting_clients--;
printf("client: %d\n\n", counting_clients);
ReleaseMutex(hMutex);
closesocket(socket_of_client);

}

void sending_message(char *message, int length_of_message) {
int i;
WaitForSingleObject(hMutex, INFINITE);
for (i = 0; i < counting_clients; i++) {
    send(socket_of_clients[i], message, 1024, 0);
}
ReleaseMutex(hMutex);
}

//client
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <stdio.h>
#include <Windows.h>

unsigned WINAPI sending_message(void *arg);
unsigned WINAPI receiving_message(void *arg);

char message[1024];
HANDLE hMutex;

int main(int argc, int *argv[]) {

WSADATA wsaData;

HANDLE sending_message_thread;
HANDLE receiving_message_thread;

struct sockaddr_in address_of_server;

if (WSAStartup(MAKEWORD(2, 2), &wsaData) == -1) {
    printf("failed\n");
}

SOCKET socket_of_client = socket(AF_INET, SOCK_STREAM, 0);

memset(&address_of_server, 0, sizeof(address_of_server));
address_of_server.sin_family = AF_INET;
address_of_server.sin_addr.s_addr = inet_addr("192.168.25.62");
address_of_server.sin_port = htons(atoi("10000"));

if (connect(socket_of_client, (struct sockaddr*)&address_of_server, sizeof(address_of_server)) == -1) {
    printf("failed\n\n");
}
else {
    printf("connected\n\n");
}

sending_message_thread = (HANDLE)_beginthreadex(NULL, 0, sending_message, (void*)&socket_of_client, 0, NULL);
receiving_message_thread = (HANDLE)_beginthreadex(NULL, 0, receiving_message, (void*)&socket_of_client, 0, NULL);

WaitForSingleObject(sending_message_thread, INFINITE);
WaitForSingleObject(receiving_message_thread, INFINITE);

closesocket(socket_of_client);

WSACleanup();

}

unsigned WINAPI sending_message(void *arg) {
WaitForSingleObject(hMutex, INFINITE);
SOCKET socket_of_client = *((SOCKET*)arg);

while (1) {
    gets(message);
    printf("\n");
    send(socket_of_client, message, 1024, 0);
}
ReleaseMutex(hMutex);
}

unsigned WINAPI receiving_message(void *arg) {
WaitForSingleObject(hMutex, INFINITE);
SOCKET socket_of_client = *((SOCKET*)arg);

while (1) {
    if ((recv(socket_of_client, message, 1024, 0)) != -1) {
        printf("from server: %s\n\n", message);
    }
}
ReleaseMutex(hMutex);
}

标签: cwindowssocketschat

解决方案


推荐阅读