Многопоточный сервер-клиент C - PullRequest
0 голосов
/ 16 декабря 2018

Здравствуйте, у меня есть некоторые проблемы с потоками и реализацией клиента и сервера, я создал 2 клиента, которые записывают в сокет бесконечные числа.чтобы клиент 2 управлял в sever.ci, создавайте потоки каждый раз, когда принимается новое соединение.он работает, но если запускается один клиент, он работает, но если я запускаю второй, первый прерывается сам;как я могу печатать попеременно?я хотел бы: G1 G2 G1 и т. д.

G1.

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>

#include <string.h>
#include <stdlib.h> 
#include <errno.h> 
#include <signal.h>
#include <time.h> 
void error(char *msg)
{
    perror(msg);
    exit(0);
}
struct message {  //dichiarazione struct
 time_t timestamp;  
 char g;  //process identifier
 int x;
};
int main(int argc, char *argv[])
{
  int sockfd, portno, n,i;
  struct message m1;
  struct sockaddr_in serv_addr;
  struct hostent *server;
  struct timespec delay;
  delay.tv_sec = 1;
  delay.tv_nsec = 0; //in microseconds
  long int offset=1000000;
  struct timeval tv;
  char buffer[256];
  if (argc < 3) {
    fprintf(stderr,"usage %s hostname port\n", argv[0]);
    exit(0);
  }
  portno = atoi(argv[2]);
  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (sockfd < 0) 
    error("ERROR opening socket");
  server = gethostbyname(argv[1]);
  if (server == NULL) {
    fprintf(stderr,"ERROR, no such host\n");
    exit(0);
  }
  bzero((char *) &serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_UNIX;
  bcopy((char *)server->h_addr, 
  (char *)&serv_addr.sin_addr.s_addr,
  server->h_length);
  serv_addr.sin_port = htons(portno);

  if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) 
    error("ERROR connecting");
    while(1){
    m1.timestamp=time(NULL);
    m1.x=i;
    m1.g=getpid();

    n = write(sockfd,&m1,sizeof(m1));
    if (n < 0) 
      error("ERROR writing to socket");
    i++;
    delay.tv_nsec=offset+rand()%offset;
    nanosleep(&delay,NULL);
  }

  return 0;
}`

Rc (сервер)

#include<stdio.h>

#include<stdlib.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<string.h>

#include <arpa/inet.h>

#include <fcntl.h> // for open

#include <unistd.h> // for close

#include<pthread.h>
struct message {  //dichiarazione struct
  time_t timestamp;  
  char g;  //process identifier
  int x;
};
struct message client_message;

char buffer[1024];

static void * socketThread(void *arg)
{ 
  while(1) {
    int newSocket = *((int *)arg);

    recv(newSocket , &client_message , sizeof(client_message), 0);

    printf("message %d  %d %ld\n",client_message.x,client_message.g,client_message.timestamp);
    fflush(stdout);
    sleep(1);
  }
}

int main(){

  int serverSocket, newSocket;

  struct sockaddr_in serverAddr;

  struct sockaddr_storage serverStorage;

  socklen_t addr_size;

  //Create the socket. 

  serverSocket = socket(AF_UNIX, SOCK_STREAM, 0);

  // Configure settings of the server address struct

  // Address family = Internet 

  serverAddr.sin_family = AF_UNIX;

  //Set port number, using htons function to use proper byte order 

  serverAddr.sin_port = htons(6005);

  //Set IP address to localhost 

  serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  //Set all bits of the padding field to 0 

  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

  //Bind the address struct to the socket 

  bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

  //Listen on the socket, with 40 max connection requests queued 

  if(listen(serverSocket,50)!=0)
  {
    printf("Error\n");
    return -1;
  }
  printf("Listening\n");

  pthread_t tid[60];

  int i = 0;

  while(1)
  {
        //Accept call creates a new socket for the incoming connection

        addr_size = sizeof serverStorage;

        newSocket = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size);

        //for each client request creates a thread and assign the client request to it to process

        //so the main thread can entertain next request

        if( pthread_create(&tid[i], NULL, socketThread, &newSocket) != 0 )
           printf("Failed to create thread\n");
        else
          ++i;
  }

  return 0;
}

Спасибо!

1 Ответ

0 голосов
/ 16 декабря 2018

Как я понимаю в коде сервера в функции потока socketThread () вы получаете значение дескриптора сокета на каждой итерации.Но когда вы принимаете новое соединение, в этот адрес записывается новое значение нового дескриптора сокета.И после этого каждый поток получает данные только из последнего сокета.

Вы должны передать socketThread () дескриптор сокета по значению (не по указателю)!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...