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