套接字编程 C [向选定的客户端发送消息]



我一直在尝试用C语言制作一个套接字程序。我的目标是尝试做多线程服务器 - 客户端消息应用程序。所以我可以将多客户端连接到服务器并从服务器发送消息。

我的代码工作,但不是我想要的。例如,如果我运行服务器并且只有一个客户端,它会向客户端发送消息,但是当我尝试连接另一个客户端时,它会逐部分发送消息。例如,如果我在服务器中编写一些东西并发送,它会转到第一个客户端;如果我写一些东西并再次发送,它会进入第二个客户端。我需要选择要发送消息的客户端,但我无法弄清楚。你能帮我吗?

这里是它的服务器代码

     #include <windows.h>
     #include <stdio.h>
     #include <conio.h>
     #include <process.h>
     #pragma comment(lib, "Ws2_32.lib")
     char buffer[100];
     int MyFunction(void* Arg)
      {
SOCKET Client = (*(int *)Arg);
while (1)
{   
    //int Socket = (*(int *)Arg);
    printf("-> ");
    gets(buffer);
    send(Client, buffer, 100, 0);   
}
_endthreadex(0);
    }
      /*--------------------------------------------------------------------            */
     void main(void)
     {
int a, b, c, d; 
int port;    
struct sockaddr_in serv_addr, cli_addr;
SOCKET Server;
SOCKET Client;
int clilen = sizeof(cli_addr);

// SOCKET  INITIALISATION
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(1, 1), &WsaDat) != 0)
{
    printf("nn WSA Initialization failed!");
    exit(1);
}

// SOCKET
Server = socket(AF_INET, SOCK_STREAM, 0);
if (Server == INVALID_SOCKET)
{
    printf("nn Socket creation failed!");
    exit(1);
}
else
    printf("nn SOCKET IS CREATED SUCCESSFULLY...");

// SERVER  ADDRESS  
serv_addr.sin_family = AF_INET;
printf("n ENTER THE SERVER IP ");
scanf_s("%d %d %d %d", &a, &b, &c, &d);
serv_addr.sin_addr.S_un.S_un_b.s_b1 = a;
serv_addr.sin_addr.S_un.S_un_b.s_b2 = b;
serv_addr.sin_addr.S_un.S_un_b.s_b3 = c;
serv_addr.sin_addr.S_un.S_un_b.s_b4 = d;
printf("n ENTER THE PORT NO ");
scanf_s("%d", &port);
serv_addr.sin_port = htons(port);

// BIND 
if (bind(Server, (struct sockaddr *)(&serv_addr), sizeof(serv_addr)) == SOCKET_ERROR)
{
    printf("nn Attempt to bind failed!STOP!!!");
}
else
    printf("nn BIND PROCESS IS CREATED SUCCESSFULLY...n ");

// LISTEN 
if (listen(Server, 5) == SOCKET_ERROR)
    printf("n Error in Listenning The Socket!n");
/*---------------------------------------------------*/
int i = 0;
while (1)
{
        printf("n SERVER IS RUNNING...n ");
            printf("Client %d is connected!n", i);

        Client = accept(Server, (struct sockaddr*)&cli_addr, &clilen);
        _beginthread(MyFunction, 0, (void *)&Client);
        i++;
}
_getch();

   }

下面是客户端代码:

    #include<stdio.h>
    #include<conio.h> 
    #include<winsock2.h>
    #include<process.h>
    #pragma comment(lib, "Ws2_32.lib")

    char buffer[100];
    void MyFunction(void * Arg)
        {
SOCKET Socket = (*(int *)Arg);
while (1)
{
    recv(Socket, buffer, 100, 0);
    printf("Server: %sn", buffer);
}
_endthread();
    }
    void main(void)
     {
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(2, 0), &WsaDat) != 0)
{
    printf("n WSA Initialization failed.");
    exit(1);
}
struct STRUCTADDR
{
    short  sin_family;
    short  sin_port;
    struct in_addr sin_addr;
    char   sin_zero[8];
};
struct STRUCTADDR p1_addr, cli_addr;
int clilen = sizeof(cli_addr);
p1_addr.sin_family = AF_INET;
int a, b, c, d;
printf("nn ENTER THE SERVER IP ");
scanf_s("%d %d %d %d", &a, &b, &c, &d);
p1_addr.sin_addr.S_un.S_un_b.s_b1 = a;
p1_addr.sin_addr.S_un.S_un_b.s_b2 = b;
p1_addr.sin_addr.S_un.S_un_b.s_b3 = c;
p1_addr.sin_addr.S_un.S_un_b.s_b4 = d;
int port;
printf("nn ENTER THE PORT NO ");
scanf_s("%d", &port);
p1_addr.sin_port = htons(port);
/*--------------------------------------------*/
SOCKET Socket;
Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET)
{
    printf("n Socket creation failed.");
    exit(1);
}
printf("n SOCKET IS CREATED SUCCESSFULLY");
if (connect(Socket, (SOCKADDR *)(&p1_addr), sizeof(p1_addr)) != 0)
{
    printf("n Failed to establish connection with server...");
}
else
    //while (1)
    //{
        printf("nn CONNECTEDn");
        _beginthread(MyFunction, 0, (void *)&Socket);
    //}
_getch();

    }

当您在服务器中接受套接字时,您需要在队列或数组中添加接受的套接字,而不是将其直接传递给您的线程函数。或者,您还可以存储通过accept()调用返回的每个对等方的IP地址,以便在要向其发送数据时可以识别给定的客户端

最新更新