Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
390 views
in Technique[技术] by (71.8m points)

c - 服务器到客户端的欢迎消息(welcome message from server to client)

I have a client program that takes 3 arguments and a server program that takes 2 arguments.

(我有一个接受3个参数的客户端程序和一个接受2个参数的服务器程序。)

For client, the first argument is address IP, the second is the port and the last one is a string(username).

(对于客户端,第一个参数是地址IP,第二个参数是端口,最后一个参数是字符串(用户名)。)

For server, the first one is port and the second argument is a string(welcome message).

(对于服务器,第一个是端口,第二个参数是字符串(欢迎消息)。)
So what I want to do is that when the client connects to the server, server sends the welcome message with client's username.

(所以我想做的是,当客户端连接到服务器时,服务器发送带有客户端用户名的欢迎消息。)
So far, I only send back client's username from server to client.

(到目前为止,我只将客户端的用户名从服务器发送回客户端。)

I don't know how I could also send welcome message.

(我不知道如何发送欢迎消息。)
PS: the method I use for sending and receiving messages from client to server and vice-versa is that I send first the strings size and after that I send the string and do the same thing with receiving.

(PS:我用于从客户端向服务器发送消息和从服务器接收消息(反之亦然)的方法是,首先发送字符串大小,然后发送字符串,然后对接收执行相同的操作。)
So here is my code:

(所以这是我的代码:)
server.c

(服务器)

#define _DEFAULT_SOURCE

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>


#define INIT_BUFFER_SIZE 1024           /* initiale buffer size */

int main (int argc, char **argv){
  struct sockaddr_in address_server;

  int res;
  int port;
  int local_socket;
  char *str_parser;
  char *str_buffer;
  int received_size = 0;
  int current_size = 0;
  int sent_size = 0;

  /* -------- structures initialisation -------- */
  memset (&address_server, 0, sizeof (struct sockaddr_in));
  str_buffer    = (char *) malloc (sizeof(char) * INIT_BUFFER_SIZE);
  if (!str_buffer) {
    fprintf (stderr, "Impossible to allocate memory.
");
    return EXIT_FAILURE;
  }
  current_size = INIT_BUFFER_SIZE;

  /* -------- Processing the parameters -------- */

  // test the number of the parameters
  if (argc != 3){
    fprintf (stderr, "maranga_srv port welcome_message
");
    free (str_buffer);
    return EXIT_FAILURE;
  }

  // Port
  errno = 0;
  port = strtol (argv[1], NULL, 10);         /* Conversion to int */
  if (errno != 0 && port == 0){
    perror ("Impossible to convert the port <%s>");
    free (str_buffer);
    return EXIT_FAILURE;
  }

  address_server.sin_port = htons (port);
  address_server.sin_family = AF_INET;
  address_server.sin_addr.s_addr = htonl (INADDR_ANY);

  /* -------- Prepration of the local socket -------- */
  // 1. Socket creation
  local_socket = socket (PF_INET, SOCK_STREAM, 0);
  if (local_socket == -1){
    fprintf (stderr, "Impossible to open the socket
");
    free (str_buffer);
    return EXIT_FAILURE;
  }

  // 2. Binding
  res = bind (local_socket, (struct sockaddr *) &address_server, sizeof (struct sockaddr_in));
  if (res == -1){
    fprintf (stderr, "Impossible to bind the socket and structure description.
");
    free (str_buffer);
    close (local_socket);   
    return EXIT_FAILURE;
  }

  /* -------- Connection -------- */
  res = listen (local_socket, 20);
  if (res == -1){
    fprintf (stderr, "Impossible to put in listen.
");
    free (str_buffer);
    close (local_socket);
    return EXIT_FAILURE;
  }

  // Infinit loop of the accept
  while (1){
    int socket_client;
    struct sockaddr_in address_client;
    socklen_t size_struct_addr_client;
    uint32_t packet_size;
    int longueur_chaine;

    socket_client = accept (local_socket, (struct sockaddr *) &address_client, &size_struct_addr_client);
    if (socket_client == -1){
      // perror ("Impossible to connect: ");
      fprintf (stderr, "Impossible to connect.
");
      continue;
    }

    /*  -------- Communication -------- */
    res = recv (socket_client, &packet_size, sizeof (uint32_t), 0);
    if (res == -1){
      // perror ("Error in size reception : ");
      fprintf (stderr, "Error in size reception.
");
      close (socket_client);
      continue;
    }

    longueur_chaine = ntohl (packet_size);

    // We assure that the buffer has enough size fot reception of the message
    if (current_size <= longueur_chaine){ /* Don't forget caracter  ! */
      char *tmp_buf; 
      tmp_buf   = realloc (str_buffer, sizeof(char) * (longueur_chaine + 1));
      if (!tmp_buf) {
        fprintf (stderr, "Impossible to reallocation
");
        free (str_buffer);
        close (local_socket);
        close (socket_client);
        exit (EXIT_FAILURE);
      }
      str_buffer = tmp_buf;
    }

    // Now we read the message
    for (str_parser = str_buffer, received_size = 0; received_size < longueur_chaine; ){
      res = recv (socket_client, str_parser, longueur_chaine - received_size, 0);
      if (res == -1){
        // perror ("Impossible to receive the message: ");
        fprintf (stderr, "Impossible to receive the message.
");
        close (socket_client);
        break;
      } 
      else if (res == 0){
        printf ("Socket closed in client side
");
        close (socket_client);
        break;
      }

      received_size += res;
      str_parser += res;
    }

    str_buffer[received_size] = ''; // ! message red from client
    // printf("message red from client is %s
", str_buffer); 

    if (received_size != longueur_chaine){
      fprintf (stderr, "Partial reception: %s
", str_buffer);
    }
    else{
      printf ("%s
", str_buffer);
    }

    // We send what was read
    longueur_chaine = strlen (str_buffer);
    packet_size = htonl (longueur_chaine);

    res = send (socket_client, &packet_size, sizeof (uint32_t), 0);
    if (res == -1){
      // perror ("Impossible to send the size of the message: ");
      fprintf (stderr, "Impossible to send the size of the message.
");
      close (socket_client);
      continue;
    }

    for (str_parser = str_buffer, sent_size = 0; sent_size < longueur_chaine; ){
      res = send (socket_client, str_parser, longueur_chaine - sent_size, 0);
      if (res == -1){
        // perror ("Impossible to send the message: ");
        fprintf (stderr, "Impossible to send the message.
");
        close (socket_client);
        continue;
      }

      sent_size += res;
      str_parser += res;
    }
    close (socket_client);
  }


  close (local_socket);
  free (str_buffer);
  return EXIT_SUCCESS;
}

client.c

(客户端)

#define _DEFAULT_SOURCE

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#define INIT_BUFFER_SIZE  1024

int main (int argc, char **argv){
  struct sockaddr_in address_client;
  struct sockaddr_in address_server;

  int res;
  int port;
  int local_socket;
  uint32_t packet_size;
  int string_size;
  char *str_parser;
  int size_sent = 0;
  char *str_buffer;
  int received_size = 0;
  int current_size = 0;

  /* -------- structures initialisation -------- */

  memset (&address_client, 0, sizeof (struct sockaddr_in));
  memset (&address_server, 0, sizeof (struct sockaddr_in));

  /* -------- Processing the parameters -------- */

  // test the number of the parameters
  if (argc != 4){
    fprintf(stderr, "maranga_cli adr_ip port username
");
    return EXIT_FAILURE;
  }

  // Adresse ip
  res = inet_aton (argv[1], &address_server.sin_addr);
  if (!res){
    fprintf (stderr, "Impossible to convert IP address <%s>
", argv[1]);
    return EXIT_FAILURE;
  }

  // Port
  errno = 0;
  port = strtol (argv[2], NULL, 10);       /* Conversion to int */

  if (errno != 0 && port == 0){
    perror ("Impossible to convert the port <%s>");
    return EXIT_FAILURE;
  }

  address_server.sin_port = htons (port);
  address_server.sin_family = AF_INET;

  /* -------- Prepration of the local socket -------- */
  // 1. Socket creation
  local_socket = socket (PF_INET, SOCK_STREAM, 0);
  if (local_socket == -1){
    fprintf (stderr, "Impossible to open the socket
");
    return EXIT_FAILURE;
  }

  // 2. Binding
  address_client.sin_family = AF_INET;
  address_client.sin_port = htons (0);
  address_client.sin_addr.s_addr = htonl (INADDR_ANY);

  res = bind (local_socket, (struct sockaddr *) &address_client, sizeof (struct sockaddr_in));
  if (res == -1){
    fprintf (stderr, "Impossible to bind the socket and structure description.
");
    close (local_socket);
    return EXIT_FAILURE;
  }

  /* -------- Connection -------- */
  res =  connect (local_socket, (struct sockaddr *) &address_server, sizeof (struct sockaddr_in));
  if (res == -1){
    // perror ("Impossible to connect to the server: ");
    fprintf (stderr, "Impossible to connect to the server.
");
    close (local_socket);
    return EXIT_FAILURE;
  }

  /* -------- Initialisation of the reception buffer -------- */
  str_buffer    = (char *) malloc (sizeof(char) * INIT_BUFFER_SIZE);
  if (!str_buffer) {
    perror ("Impossible to alocate the memory for buffer initialization: ");
    close (local_socket);
    return EXIT_FAILURE;
  }

  /* -------- Communication -------- */

  string_size = strlen (argv[3]);
  packet_size = htonl (string_size);

  res = send (local_socket, &packet_size, sizeof (uint32_t), 0);
  if (res == -1){
    // perror ("Impossible to send the size of the message: ");
    fprintf (stderr, "Impossible to send the size of the message.
");
    close (local_socket);
    free (str_buffer);
    return EXIT_FAILURE;
  }

  // Now we send the string
  for (str_parser = argv[3], size_sent = 0; size_sent < string_size; ){
    res = send (local_socket, str_parser, string_size - size_sent, 0);
    if (res == -1){
      // perror ("Impossible to send the message: ");
      fprintf (stderr, "Impossible to send the message.
");
      close (local_socket);
      free (str_buffer);
      return EXIT_FAILURE;
    }

    size_sent += res;
    str_parser += res;
  }

  res = recv (local_socket, &packet_size, sizeof (uint32_t), 0);
  if (res == -1){
    // perror ("Error in size reception: ");
    fprintf (stderr, "Error in size reception.
");
    close (local_socket);
    free (str_buffer);
    return EXIT_FAILURE;
  }

  string_size = ntohl (packet_size);

  // We assure that the buffer has enough size fot reception of the message
  if (current_size <= string_size) { /* Don't forget caracter  ! */
    char *tmp_buf;

    tmp_buf = realloc (str_buffer, sizeof(char) * (string_size + 1));
    if (!tmp_buf) {
      fprintf (stderr, "Impossible to reallocation
");
      free (str_buffer);
      close (local_socket);
      exit (EXIT_FAILURE);
    }

    str_buffer = tmp_buf;
  }

  // Now we read the message
  for (str_parser = str_buffer, received_size = 0; received_size < string_size; ){
    res = recv (local_socket, str_parser, string_size - received_size, 0);
    if (res == -1){
      // perror ("Impossible to receive the message: ");
      fprintf (stderr, "Impossible to receive the message.
");
      break;
    }
    else if (res == 0){
      printf ("Socket cl

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.8k users

...