简体   繁体   English

如何将一些数据从服务器写入连接到我的服务器的所有客户端?

[英]How can I write from some data from server to all my clients that are connected to my server?

I have a small problem and I don't find any solutions.我有一个小问题,我没有找到任何解决方案。 I have this code.我有这个代码。

Server code服务器代码

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>

#define PORT 2908
extern int errno;

typedef struct thData{
    int idThread; 
    int cl; 
}thData;

static void *treat(void *); 
void raspunde(void *);

int main ()
{
  struct sockaddr_in server;    
  struct sockaddr_in from;  
  int nr;       
  int sd;       
  int pid;
  pthread_t th[100];
    int i=0;



  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {

      return errno;
    }
  int on=1;
  setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

  bzero (&server, sizeof (server));
  bzero (&from, sizeof (from));

    server.sin_family = AF_INET;    
    server.sin_addr.s_addr = htonl (INADDR_ANY);
    server.sin_port = htons (PORT);

  /
  if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1)
    {

      return errno;
    }


  if (listen (sd, 2) == -1)
    {
      perror ("[server]Error at listen().\n");
      return errno;
    }

  while (1)
    {
      int client;
      thData * td;     
      int length = sizeof (from);


      fflush (stdout);


      if ( (client = accept (sd, (struct sockaddr *) &from, &length)) < 0)
    {
      perror ("[server]Error at accept().\n");
      continue;
    }

    td=(struct thData*)malloc(sizeof(struct thData));   
    td->idThread=i++;
    td->cl=client;

    pthread_create(&th[i], NULL, &treat, td);         

    }//while    
};              
static void *treat(void * arg)
{       
        struct thData tdL; 
        tdL= *((struct thData*)arg);    
        printf ("[thread]- %d - Waiting the message...\n", tdL.idThread);
        fflush (stdout);         
        pthread_detach(pthread_self());     
        raspunde((struct thData*)arg);
        close ((intptr_t)arg);
        return(NULL);   

};


void raspunde(void *arg)
{
        int nr, i=0;
    struct thData tdL; 
    tdL= *((struct thData*)arg);
    if (read (tdL.cl, &nr,sizeof(int)) <= 0)
            {
              printf("[Thread %d]\n",tdL.idThread);
              perror ("Error at read() from client.\n");

            }

    printf ("[Thread %d]The message is...%d\n",tdL.idThread, nr);


              nr++;      
    printf("[Thread %d]Sending the message back...%d\n",tdL.idThread, nr);

        printf("%d\n",tdL.cl );
     if (write (tdL.cl, &nr, sizeof(int)) <= 0)
        {
         printf("[Thread %d] ",tdL.idThread);
         perror ("[Thread]Error at write() from client.\n");
        }
    else
        printf ("[Thread %d]The message was sent.\n",tdL.idThread); 

}

The above code is a server that creates for every client a thread.上面的代码是一个为每个客户端创建一个线程的服务器。 The client sends a number to the server and the server will answer back to the client with the number incremented by 1.客户端向服务器发送一个数字,服务器将用递增 1 的数字回复客户端。

The question is how can I write for example the nr from the response function or a string message to all my clients that are connected on my server?问题是如何将响应函数中的 nr 或字符串消息写入服务器上连接的所有客户端?

Thank you in advance!先感谢您!

As pointed out in the comments, you'll have to keep a list of active threads (protected by a mutex!) to know who is connected to your server.正如评论中指出的那样,您必须保留活动线程列表(受互斥锁保护!)才能知道谁连接到您的服务器。 When a thread is created it would be added to the list and when execution finishes it would remove itself.当一个线程被创建时,它会被添加到列表中,当执行完成时它会移除自己。 So you sould make the following changes:因此,您应该进行以下更改:

  1. Create a global list of threads and a pthread_mutex_t to protect it (this would happen in main)创建一个全局线程列表和一个pthread_mutex_t来保护它(这会发生在主线程中)
  2. Create a function to insert a thread to the list and a function to remove threads.创建一个函数来向列表中插入一个线程,并创建一个函数来删除线程。 Don't forget to take the mutex before modifying the list and release it after.不要忘记在修改列表之前获取互斥锁并在之后释放它。
  3. Add the insert in the treat function as the first instruction and the add the remove function before close (to prevent sending to a closed connection)treat函数中添加insert 作为第一条指令,并在close之前添加remove 函数(以防止发送到关闭的连接)
  4. Define a broadcast function that takes a message, loops through the global list and sends the message to each client.定义一个广播函数,它接收一条消息,循环遍历全局列表并将消息发送到每个客户端。 Again don't forget to take the mutex while looping through the list and release it when done.再次不要忘记在循环列表时获取互斥锁并在完成后释放它。 You might also want to take into consideration skipping the sender of the broadcast.您可能还需要考虑跳过广播的发送者。

The simplest way to implement this would be to use a singly linked list where you always insert at the head (to keep insertion fast) and remove items by their id.实现这一点的最简单方法是使用一个单向链表,您总是在其中插入(以保持快速插入)并通过它们的 id 删除项目。 The function headers should look like this:函数头应该是这样的:

// your linked list
list_t* threadList;
pthread_mutex_t mutex;

void insert_list(thData* th);

// This could also return void, since to know the id you must already have the data that will be returned
thData* remove_list(int id);

// msg can have any type
void broadcast(int msg, int broadcasterId);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将数据发送到服务器上连接的多个客户端 - Sending data to multiple clients connected on my Server 如何更改服务器,以便多个客户端可以访问服务器中的共享数据? - How can I change my server so that multiple clients have access the shared data in the server? 如何确定客户端是否已连接到我的套接字? - How can I determine if clients are connected to my socket? 如何从腻子终端窗口向所有连接的客户端发送命令? - How can I send a command to all connected clients from a putty terminal window? 如何使我的服务器同时与多个客户端建立开放连接? - How can I make my server have open connections to multiple clients at the same time? aws_sdk:如何识别我的设备是否已连接到 aws 服务器 - aws_sdk: how can I identify if my device is connected to the aws server 具有多个客户端的tcp服务器将消息发送回所有连接的客户端 - tcp server with multiple clients sending message back to all connected clients 如何检查连接到服务器的客户端数量 - How to check number of clients connected to a server 如何将我的数据从缓冲区放入此结构中? - How can I get my data from my buffer into this struct? Why the C recv() function in my self-write dll stocked even broke my Labview program if I didn't keep sending data from server.c via TCP socket - Why the C recv() function in my self-write dll stocked even broke my Labview program if I didn't keep sending data from server.c via TCP socket
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM