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

时间:2017-10-30 10:33:59

标签: c sockets client-server

我一直在尝试在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("\n\n WSA Initialization failed!");
    exit(1);
}


// SOCKET
Server = socket(AF_INET, SOCK_STREAM, 0);
if (Server == INVALID_SOCKET)
{
    printf("\n\n Socket creation failed!");
    exit(1);
}
else
    printf("\n\n 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("\n\n Attempt to bind failed!STOP!!!");
}
else
    printf("\n\n 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: %s\n", 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("\n\n 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("\n\n 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("\n\n CONNECTED\n");
        _beginthread(MyFunction, 0, (void *)&Socket);

    //}
_getch();


    }

1 个答案:

答案 0 :(得分:0)

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