The last element does not apper - c

The exercise ask to resend the messages back to the client.
This exercise with some pieces of code were provided by our teacher.
I don't know why the last message that the program send does not appear. I can't understand where is the error.
I have changed the read adding the & before x. Now the x value is displayed correctly but the last value is still missing
When I insert only one value the message is missing.
The server is always running and I don't know how to fix this.
The server code is:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
/*const*/ char MESSAGE[100] = "";
char buff[100];
int main(int argc, char *argv[]) {
int simpleSocket = 0;
int simplePort = 0;
int returnStatus = 0;
struct sockaddr_in simpleServer;
if (argc != 2) {
fprintf(stderr, "Usage: %s <port>\n", argv[0]);
exit(1);
}
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);
}
else {
fprintf(stderr, "Socket created!\n");
}
/* retrieve the port number for listening */
simplePort = atoi(argv[1]);
/* setup the address structure */
/* use INADDR_ANY to bind to all local addresses */
memset(&simpleServer, '\0', sizeof(simpleServer));
simpleServer.sin_family = AF_INET;
simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
simpleServer.sin_port = htons(simplePort);
/* bind to the address and port with our socket */
returnStatus = bind(simpleSocket,(struct sockaddr *)&simpleServer,sizeof(simpleServer));
if (returnStatus == 0) {
fprintf(stderr, "Bind completed!\n");
}
else {
fprintf(stderr, "Could not bind to address!\n");
close(simpleSocket);
exit(1);
}
/* lets listen on the socket for connections */
returnStatus = listen(simpleSocket, 5);
if (returnStatus == -1) {
fprintf(stderr, "Cannot listen on socket!\n");
close(simpleSocket);
exit(1);
}
int x;
int i=0;
while (1)
{
struct sockaddr_in clientName = { 0 };
int simpleChildSocket = 0;
int clientNameLength = sizeof(clientName);
/* wait here */
simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);
if (simpleChildSocket == -1) {
fprintf(stderr, "Cannot accept connections!\n");
close(simpleSocket);
exit(1);
}
/* handle the new connection request */
/* write out our message to the client */
//read the number of messages that have to be send
read(simpleChildSocket, &x, sizeof(x));
printf("x value is: %d\n", x);
do{
// read the message from client and copy it in buffer
read(simpleChildSocket, buff, sizeof(buff));
//copy buff in MESSAGE
strcpy(MESSAGE, buff);
//sending the message
write(simpleChildSocket, MESSAGE, strlen(MESSAGE));
//cleaning the buffer
memset(&simpleServer, '\0', sizeof(simpleServer));
i++;
}while(i<x);
close(simpleChildSocket);
}
close(simpleSocket);
return 0;
}
The client code is:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]) {
int simpleSocket = 0;
int simplePort = 0;
int returnStatus = 0;
char buffer[256] = "";
struct sockaddr_in simpleServer;
if (argc != 3) {
fprintf(stderr, "Usage: %s <server> <port>\n", argv[0]);
exit(1);
}
/* create a streaming socket */
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);
}
else {
fprintf(stderr, "Socket created!\n");
}
/* retrieve the port number for connecting */
simplePort = atoi(argv[2]);
/* setup the address structure */
/* use the IP address sent as an argument for the server address */
//bzero(&simpleServer, sizeof(simpleServer));
memset(&simpleServer, '\0', sizeof(simpleServer));
simpleServer.sin_family = AF_INET;
//inet_addr(argv[2], &simpleServer.sin_addr.s_addr);
simpleServer.sin_addr.s_addr=inet_addr(argv[1]);
simpleServer.sin_port = htons(simplePort);
/* connect to the address and port with our socket */
returnStatus = connect(simpleSocket, (struct sockaddr *)&simpleServer, sizeof(simpleServer));
if (returnStatus == 0) {
fprintf(stderr, "Connect successful!\n");
}
else {
fprintf(stderr, "Could not connect to address!\n");
close(simpleSocket);
exit(1);
}
/*create the message*/
char buff[100];
int i=0, x;
//int n;
//while((buff[n++] = getchar()) != '\n');
printf("How many messages do you want to send?\n");
scanf("%d", &x);
write(simpleSocket, x, sizeof(x));
printf("Insert the message:\n");
do{
fgets(buff, 100, stdin);
write(simpleSocket, buff, sizeof(buff));
i++;
}while(i<=x);
/* get the message from the server */
returnStatus = read(simpleSocket, buffer, sizeof(buffer));
if ( returnStatus > 0 ) {
printf("%d: %s", returnStatus, buffer);
} else {
fprintf(stderr, "Return Status = %d \n", returnStatus);
}
close(simpleSocket);
return 0;
}

You have an issue with read.
This should be :
read(simpleChildSocket, &x, sizeof(x));
Read is expecting a pointer.

Related

Sending date and time as a TCP server welcome message

I have to insert this code:
time_t ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
to change the message displayed when someone connect to the server, from "Hello student!\n" to the current time and date, but I don't know where copy those two lines of code in the program and what I have to modify in the code after copying those two lines.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
const char MESSAGE[] = "Hello student!\n";
int main(int argc, char *argv[]) {
int simpleSocket = 0;
int simplePort = 0;
int returnStatus = 0;
struct sockaddr_in simpleServer;
if (argc != 2) {
fprintf(stderr, "Usage: %s <port>\n", argv[0]);
exit(1);
}
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);
}
else {
fprintf(stderr, "Socket created!\n");
}
/* retrieve the port number for listening */
simplePort = atoi(argv[1]);
/* setup the address structure */
/* use INADDR_ANY to bind to all local addresses */
memset(&simpleServer, '\0', sizeof(simpleServer));
simpleServer.sin_family = AF_INET;
simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
simpleServer.sin_port = htons(simplePort);
/* bind to the address and port with our socket */
returnStatus = bind(simpleSocket,(struct sockaddr *)&simpleServer,sizeof(simpleServer));
if (returnStatus == 0) {
fprintf(stderr, "Bind completed!\n");
}
else {
fprintf(stderr, "Could not bind to address!\n");
close(simpleSocket);
exit(1);
}
/* lets listen on the socket for connections */
returnStatus = listen(simpleSocket, 5);
if (returnStatus == -1) {
fprintf(stderr, "Cannot listen on socket!\n");
close(simpleSocket);
exit(1);
}
while (1)
{
struct sockaddr_in clientName = { 0 };
int simpleChildSocket = 0;
int clientNameLength = sizeof(clientName);
/* wait here */
simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);
if (simpleChildSocket == -1) {
fprintf(stderr, "Cannot accept connections!\n");
close(simpleSocket);
exit(1);
}
/* handle the new connection request */
/* write out our message to the client */
write(simpleChildSocket, MESSAGE, strlen(MESSAGE));
close(simpleChildSocket);
}
close(simpleSocket);
return 0;
}
Thank you for your answers
A little introduction: about the original program
The program starts creating a socket and setting it to listen to a specific port, passed as an argument to your program with a command line such as programName <port>.
The port number is retrieved with the line simplePort = atoi(argv[1]);. There could have been a stricter check on the parameter (atoi() doesn't check if a number is actually provided), but I suppose it is ok for an entry level educational program.
After that, with the line
simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);
the accept() function blocks until a connection request from a TCP client is received. As soon as the TCP handshake is completed (SYN / SYN-ACK / ACK, it is
called three-way handshake) a socket handle is returned (in your case simpleChildSocket) and that can be used to exchange data with the client.
The welcome message
After the accept is completed, and we are sure that all went fine, we soon come to our welcome message. With the lines
/* write out our message to the client */
write(simpleChildSocket, MESSAGE, strlen(MESSAGE));
the characters contained in the MESSAGE string (defined with the constant const char MESSAGE[] = "Hello student!\n";) are sent through write() function. Its parameters are
the socket descriptor
the pointer to the buffer to be sent
the number of bytes to be sent (in this case it corresponds to the length of MESSAGE, calculated with strlen(MESSAGE)
Note: write function can actually be used, but it is an unconventional choice. In fact it is a general function but when writing to sockets send() is actually used.
How to achieve you goal
All you have to do is to substitute MESSAGE in the write() call with the string containing the date:
{
char buff[30+1];
time_t ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.30s\r\n", ctime(&ticks));
/* write out our message to the client */
write( simpleChildSocket, buff, strlen(buff) );
}
Don't forget to define your buff character buffer. I defined it locally but you can also allocate it dynamically.
The code provided by your teacher copies the time calculate with ctime() in the buff array (I increased its size in order to make sure that the whole datetime can be contained in it).
Then we call write as we previously did, just substituting MESSAGE and strlen(MESSAGE) with the new string buff and strlen(buff).
I have solved
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
/*const*/ char MESSAGE[100] = "";
char buff[100];
int main(int argc, char *argv[]) {
int simpleSocket = 0;
int simplePort = 0;
int returnStatus = 0;
struct sockaddr_in simpleServer;
if (argc != 2) {
fprintf(stderr, "Usage: %s <port>\n", argv[0]);
exit(1);
}
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);
}
else {
fprintf(stderr, "Socket created!\n");
}
/* retrieve the port number for listening */
simplePort = atoi(argv[1]);
/* setup the address structure */
/* use INADDR_ANY to bind to all local addresses */
memset(&simpleServer, '\0', sizeof(simpleServer));
simpleServer.sin_family = AF_INET;
simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
simpleServer.sin_port = htons(simplePort);
/* bind to the address and port with our socket */
returnStatus = bind(simpleSocket,(struct sockaddr *)&simpleServer,sizeof(simpleServer));
if (returnStatus == 0) {
fprintf(stderr, "Bind completed!\n");
}
else {
fprintf(stderr, "Could not bind to address!\n");
close(simpleSocket);
exit(1);
}
/* lets listen on the socket for connections */
returnStatus = listen(simpleSocket, 5);
if (returnStatus == -1) {
fprintf(stderr, "Cannot listen on socket!\n");
close(simpleSocket);
exit(1);
}
while (1)
{
struct sockaddr_in clientName = { 0 };
int simpleChildSocket = 0;
int clientNameLength = sizeof(clientName);
/* wait here */
simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);
if (simpleChildSocket == -1) {
fprintf(stderr, "Cannot accept connections!\n");
close(simpleSocket);
exit(1);
}
/* handle the new connection request */
/* write out our message to the client */
time_t ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
strcpy(MESSAGE, buff);
write(simpleChildSocket, MESSAGE, strlen(MESSAGE));
close(simpleChildSocket);
}
close(simpleSocket);
return 0;
}

multi threaded file transfer with socket problem

what I want to make is the multi-client,server file transfer with socket.
it compiled well and seems realistic.
But Problem is, Code won't act properly and client don't send file to server folder.
I don't know what is the problem.
Can anybody see code and tell what is the problem?
it would be grateful if you change my code also.
client
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h> /* getprotobyname */
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
// NOTE/BUG: this didn't provide enough space for a 5 digit port + EOS char
#if 0
enum { PORTSIZE = 5 };
#else
enum { PORTSIZE = 6 };
#endif
void
sig_handler(int signo)
{
if (signo == SIGINT)
printf("!! OUCH, CTRL - C received on client !!\n");
}
int
main(int argc, char **argv)
{
struct addrinfo hints,
*res;
char *server_hostname = "127.0.0.1";
char file_path[BUFSIZ];
char *server_reply = NULL;
char *user_input = NULL;
char buffer[BUFSIZ];
int filefd;
int sockfd;
ssize_t read_return;
struct hostent *hostent;
unsigned short server_port = 12345;
char portNum[PORTSIZE];
char remote_file[BUFSIZ];
int select;
char *client_server_files[BUFSIZ];
int i = 0;
int j;
char protoname[] = "tcp";
struct protoent *protoent;
struct sockaddr_in sockaddr_in;
in_addr_t in_addr;
// char filename_to_send[BUFSIZ];
if (argc != 3) {
fprintf(stderr, "Usage ./client <ip> <port>\n");
exit(EXIT_FAILURE);
}
server_hostname = argv[1];
server_port = strtol(argv[2], NULL, 10);
/* Get socket. */
protoent = getprotobyname(protoname);
if (protoent == NULL) {
perror("getprotobyname");
exit(EXIT_FAILURE);
}
sockfd = socket(AF_INET, SOCK_STREAM, protoent->p_proto);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
/* Prepare sockaddr_in. */
hostent = gethostbyname(server_hostname);
if (hostent == NULL) {
fprintf(stderr, "error: gethostbyname(\"%s\")\n", server_hostname);
exit(EXIT_FAILURE);
}
in_addr = inet_addr(inet_ntoa(*(struct in_addr*)*(hostent->h_addr_list)));
if (in_addr == (in_addr_t)-1) {
fprintf(stderr, "error: inet_addr(\"%s\")\n", *(hostent->h_addr_list));
exit(EXIT_FAILURE);
}
sockaddr_in.sin_addr.s_addr = in_addr;
sockaddr_in.sin_family = AF_INET;
sockaddr_in.sin_port = htons(server_port);
/* Do the actual connection. */
if (connect(sockfd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) == -1) {
perror("connect");
return EXIT_FAILURE;
}
while (1) {
if (signal(SIGINT, sig_handler)) {
break;
}
puts("connected to the server");
puts("-----------------");
puts("|1 - listLocal| \n|2 - listServer| \n|3 - sendFile| \n|4 - help| \n|5 - exit| ");
puts("-----------------");
while (1) {
printf("------%d",select);
scanf("%d", &select);
while ( getchar() != '\n' );
switch (select) {
case 1: // list files of client's directory
system("find . -maxdepth 1 -type f | sort");
sprintf(remote_file, "%s", "listLocal");
send(sockfd, remote_file, sizeof(remote_file), 0);
break;
case 2: // listServer
sprintf(remote_file, "%s", "listServer");
send(sockfd, remote_file, sizeof(remote_file), 0);
puts("---- Files btw Server and the Client ----");
for (j = 0; j < i; ++j) {
puts(client_server_files[j]);
}
break;
case 3: // send file
memset(file_path, 0, sizeof file_path);
scanf("%s", file_path);
sprintf(remote_file, "%s", "sendFile");
send(sockfd, remote_file, sizeof(remote_file), 0);
memset(remote_file, 0, sizeof remote_file);
// send file name to server
sprintf(remote_file, "%s", file_path);
send(sockfd, remote_file, sizeof(remote_file), 0);
filefd = open(file_path, O_RDONLY);
if (filefd == -1) {
perror("open send file");
//exit(EXIT_FAILURE);
break;
}
while (1) {
read_return = read(filefd, buffer, BUFSIZ);
if (read_return == 0)
break;
if (read_return == -1) {
perror("read");
//exit(EXIT_FAILURE);
break;
}
if (write(sockfd, buffer, read_return) == -1) {
perror("write");
//exit(EXIT_FAILURE);
break;
}
}
// add files in char pointer array
client_server_files[i++] = file_path;
close(filefd);
break;
case 5:
sprintf(remote_file, "%s", "exit");
send(sockfd, remote_file, sizeof(remote_file), 0);
free(user_input);
free(server_reply);
exit(EXIT_SUCCESS);
default:
puts("Wrong selection!");
break;
}
}
}
free(user_input);
free(server_reply);
exit(EXIT_SUCCESS);
}
server
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h> /* getprotobyname */
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <pthread.h>
struct client {
socklen_t client_len;
struct sockaddr_in client_address;
int client_sockfd;
pthread_t thread;
};
// NOTE: provide enough space for a 5 digit port + EOS char
enum { PORTSIZE = 6 };
double cpu_time_used;
clock_t start, end;
void *forClient(void *ptr);
void portCleaner(const char* port_num) {
char temp[100] = "sudo lsof -t -i tcp:";
sprintf(temp, "%s%s%s", temp, port_num, " | xargs kill -9;");
system(temp);
//puts(temp);
}
void
sig_handler(int signo)
{
if (signo == SIGINT)
printf("!! OUCH, CTRL - C received by server !!\n");
}
int
main(int argc, char **argv)
{
struct addrinfo hints,
*res;
int enable = 1;
//int filefd; // NOTE: this is never initialized/used
int server_sockfd;
unsigned short server_port = 12345u;
char portNum[PORTSIZE];
struct sockaddr_in server_address;
struct protoent *protoent;
char protoname[] = "tcp";
#if 0
int socket_index = 0;
#else
struct client *ctl;
#endif
if (argc != 2) {
fprintf(stderr, "Usage ./server <port>\n");
exit(EXIT_FAILURE);
}
server_port = strtol(argv[1], NULL, 10);
/* Create a socket and listen to it.. */
protoent = getprotobyname(protoname);
if (protoent == NULL) {
perror("getprotobyname");
exit(EXIT_FAILURE);
}
server_sockfd = socket(
AF_INET,
SOCK_STREAM,
protoent->p_proto
);
if (server_sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
if (setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) < 0) {
perror("setsockopt(SO_REUSEADDR) failed");
exit(EXIT_FAILURE);
}
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(server_port);
if (bind(
server_sockfd,
(struct sockaddr*)&server_address,
sizeof(server_address)
) == -1
) {
perror("bind");
portCleaner(argv[1]);
exit(EXIT_FAILURE);
}
if (listen(server_sockfd, 5) == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
fprintf(stderr, "listening on port %d\n", server_port);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,1);
start = clock();
while (1) {
ctl = malloc(sizeof(struct client));
if (ctl == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
ctl->client_len = sizeof(ctl->client_address);
puts("waiting for client");
ctl->client_sockfd = accept(server_sockfd,
(struct sockaddr *) &ctl->client_address, &ctl->client_len);
if (ctl->client_sockfd < 0) {
perror("Cannot accept connection\n");
close(server_sockfd);
exit(EXIT_FAILURE);
}
pthread_create(&ctl->thread, &attr, forClient, ctl);
}
return EXIT_SUCCESS;
}
void *
forClient(void *ptr)
{
end = clock();
cpu_time_used = 1000 * (((double) (end - start)) / CLOCKS_PER_SEC);
#if 0
int connect_socket = (int) ptr;
#else
struct client *ctl = ptr;
int connect_socket = ctl->client_sockfd;
#endif
int filefd;
ssize_t read_return;
char buffer[BUFSIZ];
char *file_path;
char receiveFileName[BUFSIZ];
char cmd[BUFSIZ];
// Thread number means client's id
printf("Connected time [%lf] --- Thread number [%ld]\n", cpu_time_used, pthread_self());
// until stop receiving go on taking information
while (recv(connect_socket, receiveFileName, sizeof(receiveFileName), 0)) {
if((strcmp(receiveFileName, "listServer") == 0
|| strcmp(receiveFileName, "listLocal") == 0 || strcmp(receiveFileName, "help") == 0
|| strcmp(receiveFileName, "exit") == 0 || strcmp(receiveFileName, "sendFile") == 0)) {
printf("--- Command <%s> ---\n", receiveFileName);
continue;
}
file_path = receiveFileName;
fprintf(stderr, "is the file name received? ? => %s\n", file_path);
filefd = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (filefd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
do {
read_return = read(connect_socket, buffer, BUFSIZ);
if (read_return == -1) {
perror("read");
exit(EXIT_FAILURE);
}
if (write(filefd, buffer, read_return) == -1) {
perror("write");
exit(EXIT_FAILURE);
}
} while (read_return > 0);
// NOTE/BUG: filefd was never closed
close(filefd);
}
fprintf(stderr, "Client dropped connection\n");
// NOTE: do all client related cleanup here
// previously, the main thread was doing the close, which is why it had
// to do the pthread_join
close(connect_socket);
free(ctl);
return (void *) 0;
}
while (recv(connect_socket, receiveFileName, sizeof(receiveFileName), 0)) {
if((strcmp(receiveFileName, "listServer") == 0
You throw away the return value of recv, which is the only way to know how many bytes of data you received. So the rest of your code has no idea what data you actually received.
Then you pass the chunk of data you read to strcmp. But it's just a chunk of arbitrary data. It's not a string. You cannot pass something to strcmp unless it's a string.
You are missing a message protocol. Your client is supposed to send messages and your server needs to process messages. To do this, you need a message protocol that defines what a message is and then you need to write code to send and receive messages.
The recv function has no idea what your messages are and has no way to know where the message ends.
Since you're not experienced at using TCP, you should always start by specifying the protocol the server and client will use on top of TCP. If it's a message protocol, define specifically how messages will be represented on the wire. It may be helpful to look at the specifications for existing protocols layered on top of TCP such as SMTP or HTTP.
Otherwise, use a library that provides functions to send and receive messages instead of trying to use TCP directly.

C TCP client-server segmentation fault problem

I am trying to implement a client-server program in C with TCP for an exercise. The server should be able to serve many clients. The clients asks for some files that the server sends them. Each time the client ends, the server crashes with a segmentation fault error. It prints the "end of service", looking at gdb it also returns to the main function, but it never prints the "prova" after the call to the 'service' function, inside the loop.
Here you can see my server and below my client
/*
* TEMPLATE
*/
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <rpc/xdr.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "../errlib.h"
#include "../sockwrap.h"
#define BUFLEN 1024 /* Buffer length */
char *prog_name;
char *err="-ERR\r\n";
void service(int s);
uint32_t getFileCreationTime(char *filename);
int main (int argc, char *argv[])
{
int conn_request_skt; /* passive socket */
uint16_t lport_n, lport_h; /* port used by server (net/host ord.) */
int bklog = 2; /* listen backlog */
int s; /* connected socket */
socklen_t addrlen;
struct sockaddr_in saddr, caddr; /* server and client addresses */
prog_name = argv[0];
if (argc != 2)
{
printf("Usage: %s <port number>\n", prog_name);
exit(1);
}
/* get server port number */
if (sscanf(argv[1], "%" SCNu16, &lport_h)!=1)
err_sys("Invalid port number");
lport_n = htons(lport_h);
/* create the socket */
printf("creating socket...\n");
s = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("done, socket number %u\n",s);
/* bind the socket to any local IP address */
bzero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = lport_n;
saddr.sin_addr.s_addr = INADDR_ANY;
showAddr("Binding to address", &saddr);
Bind(s, (struct sockaddr *) &saddr, sizeof(saddr));
printf("done.\n");
/* listen */
printf ("Listening at socket %d with backlog = %d \n",s,bklog);
Listen(s, bklog);
printf("done.\n");
conn_request_skt = s;
/* main server loop */
for (;;)
{
printf("loop again\n");
/* accept next connection */
addrlen = sizeof(struct sockaddr_in);
s = Accept(conn_request_skt, (struct sockaddr *) &caddr, &addrlen);
showAddr("Accepted connection from", &caddr);
printf("new socket: %u\n",s);
/* serve the client on socket s */
service(s);
printf("Prova\n");
}
return 0;
}
uint32_t getFileCreationTime(char *filename)
{
struct stat *attr;
stat(filename, attr);
return attr->st_mtime;
}
void service(int s)
{
char rbuf[BUFLEN+1]; /* reception buffer */
char buf[BUFLEN]; /* sending buffer */
char sbuf[BUFLEN]; /* buffer that will contain the dimension of the file */
int n;
char *get, *filename, filename_stats[20];
size_t len;
uint32_t bsent, dimension, modtime;
FILE *fp;
struct stat * fstatus;
for (;;)
{
n=recv(s, rbuf, BUFLEN-1, 0);
if (n < 0)
{
printf("Read error\n");
close(s);
printf("Socket %d closed\n", s);
break;
}
else if (n==0)
{
printf("Connection closed by party on socket %d\n",s);
close(s);
break;
}
else
{
rbuf[n]=0;
get = strtok(rbuf, " ");
filename = strtok(NULL, "\r\n");
if(strcmp(get, "GET") == 0)
{
printf("\nA client requested the file '%s'\n", filename);
fp = fopen(filename, "rb");
if (fp == NULL)
{
printf("-ERR\tCould not open the file\n");
if(writen(s, err, 6) != 6)
printf("Write error\n");
}
fseek (fp, 0, SEEK_END);
dimension = ftell (fp);
//dimension--;
fseek (fp, 0, SEEK_SET);
sprintf(sbuf, "+OK\r\n");
printf("Sending:\n%s\n", sbuf);
if(writen(s, sbuf, 5) != 5)
printf("Write error\n");
//printf("Sending:\n%d\n", dimension);
//dimension = htonl(dimension);
//printf("dimension net=%d\n", dimension);
if(writen(s, &dimension, 4) != 4)
printf("Write error\n");
//dimension = ntohl(dimension);
printf("dimension=%d\n", dimension);
bsent=0;
while(bsent!=dimension)
{
if(dimension-bsent < BUFLEN)
{
//printf("bytes to send <BUFLEN\n");
fread (buf, 1, dimension-bsent, fp);
printf("Sending last %d bytes of the file\n", dimension-bsent);
if(writen(s, buf, dimension-bsent) != dimension-bsent)
printf("Write error\n");
bsent+=dimension-bsent;
}
else
{
//printf("bytes to send > BUFLEN\n");
fread (buf, 1, BUFLEN, fp);
//printf("Sending:\n%s\n", buf);
if(writen(s, buf, BUFLEN) != BUFLEN)
printf("Write error\n");
bsent+=BUFLEN;
printf("Bytes sent: %d\n", bsent);
}
}
fclose (fp);
modtime = getFileCreationTime(filename);
printf("Sending:\n%d\n", modtime);
//modtime = htonl(modtime);
if(writen(s, &modtime, 4) != 4)
printf("Write error\n");
printf("File '%s' correctly sent to the requesting client\n", filename);
}
else //invalid request
{
printf("-ERR\tINVALID REQUEST\n");
if(writen(s, err, 6) != 6)
printf("Write error\n");
}
}
}
printf("End of service\n");
return;
}
And here's the client:
/*
* TEMPLATE
*/
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <rpc/xdr.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "../errlib.h"
#include "../sockwrap.h"
#define BUFLEN 1024 /* Buffer length */
char *prog_name;
int main (int argc, char *argv[])
{
char buf[BUFLEN]; /* transmission buffer */
char rbuf[BUFLEN]; /* receiving buffer */
char ok[5]; /* buffer used to receive the "+OK" message */
uint16_t tport_n, tport_h; /* server port number (net/host ord) */
char **filenames, *out="_out";
FILE* fp;
size_t len;
int s, result, i;
struct sockaddr_in saddr; /* server address structure */
struct in_addr sIPaddr; /* server IP addr. structure */
ssize_t nreadok, nread;
size_t nleft;
uint32_t breceived , bytes, timestamp;
prog_name = argv[0];
if(argc<4)
{
printf("Error! Usage: %s IP_addr port_number filename1 filename2 filename3 ...\n", prog_name);
return -1;
}
filenames = (char **) malloc(argc*sizeof(char*));
for(i=3; i<argc; i++)
{
filenames[i-3] = (char*) malloc (30*sizeof(char));
strcpy(filenames[i-3], argv[i]);
}
/* input IP address and port of server */
result = inet_aton(argv[1], &sIPaddr);
if (!result)
err_quit("Invalid address");
if (sscanf(argv[2], "%" SCNu16, &tport_h)!=1)
err_quit("Invalid port number");
tport_n = htons(tport_h);
/* create the socket */
printf("Creating socket\n");
s = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("done. Socket fd number: %d\n",s);
/* prepare address structure */
bzero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = tport_n;
saddr.sin_addr = sIPaddr;
/* connect */
showAddr("Connecting to target address", &saddr);
Connect(s, (struct sockaddr *) &saddr, sizeof(saddr));
printf("done.\n");
for(i=3; i<argc; i++)
{
//filename=argv[i];
sprintf(buf, "GET %s\r\n", filenames[i-3]); //creating the request "GET filename"
len = strlen(buf);
printf("\n%s", buf);
if(writen(s, buf, len) != len) //sending the request
{
printf("Write error\n");
}
printf("\nwaiting for response...\n");
//filename=argv[i];
//char rbuf[BUFLEN];
nread = readn(s, rbuf, 5); //receiving "+OK\r\n"
if(nread == 0)
printf("Connection closed\n");
if(rbuf[0] == '-')
{
nread = readn(s, rbuf, 1); //remaining byte of the "-ERR\r\n" message
if(nread==0)
printf("Connection closed\n");
printf("-ERROR! The server could not answer the request\n");
close(s);
return -1;
}
bytes=0;
//printf("Bytes 0=%d\n", bytes);
nread = readn(s, &bytes, 4); //receiving the dimension
if(nread == 0)
printf("Connection closed\n");
//printf("Bytes net=%d\n", bytes);
//bytes = ntohl(bytes);
printf("Dimension of the file = %d\n", bytes);
/*
nread = readn(s, rbuf, bytes-1); //receiving the file
if(nread == 0)
printf("Connection closed\n");
*/
strcat(filenames[i-3], "_copy");
fp = fopen(filenames[i-3], "wb"); //creating the file "filename_out"
if (fp == NULL)
{
printf("Could not open the file\n");
}
else
{
//coping data into the copy of the file
breceived=0;
while(1)
{
rbuf[0]=0;
if(bytes-breceived < BUFLEN)
{
//printf("bytes to receive <BUFLEN\n");
printf("Receiving: %d bytes of the file\n", bytes-breceived);
if(readn(s, rbuf, bytes-breceived) != bytes-breceived)
printf("Connection closed\n");
//printf("receiving:\n%s\n", rbuf);
//fputs(rbuf, fp);
fwrite(rbuf, 1, bytes-breceived, fp);
breceived+=bytes-breceived;
printf("Bytes received: %d\n", breceived);
break;
}
else
{
printf("bytes to receive(>BUFLEN) = %d\n", bytes-breceived);
//printf("receiving:\n%s\n", rbuf);
if(readn(s, rbuf, BUFLEN) != BUFLEN)
printf("Connection closed\n");
//printf("receiving:\n%s\n", rbuf);
//fputs(rbuf, fp);
fwrite(rbuf, 1, BUFLEN, fp);
breceived=breceived+BUFLEN;
printf("Bytes received: %d\n", breceived);
}
}
}
if(rbuf[0] == '-')
{
nread = readn(s, rbuf, 1); //remaining byte of the "-ERR\r\n" message
if(nread==0)
printf("Connection closed\n");
printf("-ERROR! The server could not answer the request\n");
close(s);
return -2;
}
//rbuf[bytes]=0;
nread = readn(s, &timestamp, 4); //receiving the timestamp
if(nread == 0)
printf("Connection closed\n");
//timestamp = ntohl(timestamp);
printf("\nFile received: '%s'\t %d bytes \t last mod: %d\n\n", filenames[i-3], bytes, timestamp);
fclose(fp);
}
printf("Closing the connection\n");
close(s);
return 0;
}

C file server and client hanging on recv

So I am trying to work on this toy client file server problem.
The iterative version works fine, but when I attempt to fork each new connection in the server code, the client code hangs on the recv call.
I am fairly sure the issue is with the peer_socket, but I have been unable to find my mistake.
It completes just fine if I hit the server with a Ctrl-c though.
CLIENT CODE:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT_NUMBER 5108
#define SERVER_ADDRESS "localhost"
//#define FILENAME "test.txt"
int main(int argc, char **argv)
{
int client_socket;
ssize_t len;
struct sockaddr_in remote_addr;
char buffer[BUFSIZ];
char filename[256];
char local_filename[256];
int file_size;
FILE *received_file;
int remain_data = 0;
/* Zeroing remote_addr struct */
memset(&remote_addr, 0, sizeof(remote_addr));
memset(local_filename, 0, sizeof(local_filename));
if(argc >1){
strncpy(local_filename, argv[1], 256);
}
/* Construct remote_addr struct */
remote_addr.sin_family = AF_INET;
inet_pton(AF_INET, SERVER_ADDRESS, &(remote_addr.sin_addr));
remote_addr.sin_port = htons(PORT_NUMBER);
/* Create client socket */
client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1)
{
fprintf(stderr, "Error creating socket --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
//Prompt for file to retrieve
printf("Enter file name: ");
fgets(filename,sizeof(filename),stdin);
printf("Getting file %s", filename);
/* Connect to the server */
if (connect(client_socket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
{
fprintf(stderr, "Error on connect --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
//Send filename to server
/*if(!send(client_socket,filename, sizeof(filename))) {
printf("Error sending filename\n");
exit(EXIT_FAILURE);
}*/
send(client_socket,filename, sizeof(filename),0);
printf("success\n");
/* Receiving file size */
memset(&buffer, 0, sizeof(buffer));
recv(client_socket, buffer, sizeof(buffer), 0);
file_size = atoi(buffer);
fprintf(stdout, "\nFile size : %d\n", file_size);
if(!local_filename[0]) {
received_file = fopen("test2.txt", "w");
}else{
received_file = fopen(local_filename, "w");
}
if (received_file == NULL)
{
fprintf(stderr, "Failed to open file foo --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
remain_data = file_size;
//THIS IS THE LOOP THAT HANGS!
while (((len = recv(client_socket, buffer, BUFSIZ, 0)) > 0) && (remain_data > 0))
{
fwrite(buffer, sizeof(char), len, received_file);
remain_data -= len;
fprintf(stdout, "Receive %d bytes and we hope :- %d bytes\n", len, remain_data);
}
printf("did we reach here in the code?\n");
fclose(received_file);
printf("did we reach here in the code?\n");
close(client_socket);
return 0;
}
SERVER CODE:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <signal.h>
#define PORT_NUMBER 5108
#define SERVER_ADDRESS "localhost"
//#define FILE_TO_SEND "hello.c"
int main(int argc, char **argv)
{
int server_socket;
socklen_t global_sock_len;
struct sockaddr_in server_addr;
struct sockaddr_in peer_addr;
/* Create server socket */
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1)
{
fprintf(stderr, "Error creating socket --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Zeroing server_addr struct */
memset(&server_addr, 0, sizeof(server_addr));
/* Construct server_addr struct */
server_addr.sin_family = AF_INET;
inet_pton(AF_INET, SERVER_ADDRESS, &(server_addr.sin_addr));
server_addr.sin_port = htons(PORT_NUMBER);
/* Bind */
if ((bind(server_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) == -1)
{
fprintf(stderr, "Error on bind --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Listening to incoming connections */
if ((listen(server_socket, 5)) == -1)
{
fprintf(stderr, "Error on listen --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
//attempt multiple connections via fork
int peer_socket;
int fid;
while(1) {
bool servexit = false;
printf("did we reach HERE in the code?%d\n",getpid());
peer_socket = accept(server_socket, (struct sockaddr *) &peer_addr, &global_sock_len);
//printf("did we reach HERE in the code?\n");
if (peer_socket == -1) {
fprintf(stderr, "Error on accept --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
if((fid = fork()) == -1) {
printf("error\n");
close(peer_socket);
//continue;
}else if(fid > 0){
printf("parent\n");
close(peer_socket);
//continue;
}else if(fid == 0) {
printf("child\n");
socklen_t sock_len;
ssize_t len;
int fd;
int sent_bytes = 0;
char FILE_TO_SEND[256];
char file_size[256];
struct stat file_stat;
off_t offset;
int remain_data;
//int peer_socket = peer_socket;
recv(peer_socket, FILE_TO_SEND, sizeof(FILE_TO_SEND), 0);
printf("Client requested %s", FILE_TO_SEND);
if (strlen(FILE_TO_SEND) > 1) {
strtok(FILE_TO_SEND, "\n");
}
//check for server close command from client
if(strcmp(FILE_TO_SEND,"quit") == 0){
servexit = true;
printf("Quiting server\n");
close(server_socket);
close(peer_socket);
pid_t pid = getppid();
kill(pid, SIGKILL);
exit(0);
}else {
fd = open(FILE_TO_SEND, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "Error opening file --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Get file stats */
if (fstat(fd, &file_stat) < 0) {
fprintf(stderr, "Error fstat --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "File Size: \n%d bytes\n", file_stat.st_size);
sock_len = sizeof(struct sockaddr_in);
fprintf(stdout, "Accept peer --> %s\n", inet_ntoa(peer_addr.sin_addr));
sprintf(file_size, "%d", file_stat.st_size);
/* Sending file size */
len = send(peer_socket, file_size, sizeof(file_size), 0);
if (len < 0) {
fprintf(stderr, "Error on sending greetings --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "Server sent %d bytes for the size\n", len);
//fflush((FILE*)peer_socket);
offset = 0;
remain_data = file_stat.st_size;
/* Sending file data */
while (((sent_bytes = sendfile(peer_socket, fd, &offset, BUFSIZ)) > 0) && (remain_data > 0)) {
fprintf(stdout,
"1. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n",
sent_bytes, offset, remain_data);
remain_data -= sent_bytes;
fprintf(stdout,
"2. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n",
sent_bytes, offset, remain_data);
}
}
break;
}
}
return 0;
}
Ok, so, it turns out that sendfile() doesn't play as nicely as send() in this situation. I found two fixes.
1.) Use send() instead of sendfile()
2.) Retry in both sendfile() (Server) and recv() (client) if either returns -1 (error)

Calculate average of numbers in TCP connection

I have to calculate the average of numbers received by a server, then send it to client in a TCP connection in C. The program must be like this:
Client sends a message to server with numbers(for example): 2 10 12 --> 2 is number of data and 10 and 12 are the data. Server receives the numbers and sends the count of them to client(in this example count is "2"). It continues until client sends number "0". At this point, server has to send a message to client with number of data calculated and, in the same line, the average of them. If i send "2 10 12" and "2 5 6", server sends to client the message: "4 8.25". "4" is the number of data to calculate and "8.25" is average.
Until now i made the first part for client:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]) {
int simpleSocket = 0;
int simplePort = 0;
int returnStatus= 0;
char buffsend[256];
char buffrecv[256];
char buff[256];
int i, n, length, ndata;
float average=0;
struct sockaddr_in simpleServer;
if (3 != argc) {
fprintf(stderr, "Usage: %s <server> <port>\n", argv[0]);
exit(1);
}
/* create a streaming socket */
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);
}
else {
fprintf(stderr, "Socket created!\n");
}
/* retrieve the port number for connecting */
simplePort = atoi(argv[2]);
/* setup the address structure */
/* use the IP address sent as an argument for the server address */
//bzero(&simpleServer, sizeof(simpleServer));
memset(&simpleServer, '\0', sizeof(simpleServer));
simpleServer.sin_family = AF_INET;
//inet_addr(argv[2], &simpleServer.sin_addr.s_addr);
simpleServer.sin_addr.s_addr=inet_addr(argv[1]);
simpleServer.sin_port = htons(simplePort);
/* connect to the address and port with our socket */
returnStatus = connect(simpleSocket, (struct sockaddr *)&simpleServer, sizeof(simpleServer));
if (returnStatus == 0) {
fprintf(stderr, "Connect successful!\n");
}
else {
fprintf(stderr, "Could not connect to address!\n");
close(simpleSocket);
exit(1);
}
/* get the message from the server */
do {
bzero(buffsend, 256);
printf("insert num dati or terminate(write '0'): ");
fgets(buffsend,256,stdin);
n=atoi(buffsend);
if(n>6) {
printf("Error\n");
}
else {
length=strlen(buffsend);
for(i=0;i<n;i++) {
printf("insert number: ");
length=strlen(buffsend);
buffsend[length-1]=' ';
fgets(buffsend+length,256-length,stdin);
write(simpleSocket, buffsend, strlen(buffsend));
read(simpleSocket, buffrecv, 256);
}
ndata=atoi(buffrecv);
printf("DT %d\n", ndata);
}
} while((n!=0) && (n>0));
close(simpleSocket);
return 0;
}
And this for server:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int simpleSocket = 0;
int simplePort = 0;
int returnStatus = 0;
char buff[256];
char message[256];
int n, i, DT;
int count=0;
float average=0;
struct sockaddr_in simpleServer;
if (2 != argc) {
fprintf(stderr, "Usage: %s <port>\n", argv[0]);
exit(1);
}
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);
}
else {
fprintf(stderr, "Socket created!\n");
}
/* retrieve the port number for listening */
simplePort = atoi(argv[1]);
/* setup the address structure */
/* use INADDR_ANY to bind to all local addresses */
memset(&simpleServer, '\0', sizeof(simpleServer));
simpleServer.sin_family = AF_INET;
simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
simpleServer.sin_port = htons(simplePort);
/* bind to the address and port with our socket */
returnStatus = bind(simpleSocket,(struct sockaddr *)&simpleServer,sizeof(simpleServer));
if (returnStatus == 0) {
fprintf(stderr, "Bind completed!\n");
}
else {
fprintf(stderr, "Could not bind to address!\n");
close(simpleSocket);
exit(1);
}
/* lets listen on the socket for connections */
returnStatus = listen(simpleSocket, 5);
if (returnStatus == -1) {
fprintf(stderr, "Cannot listen on socket!\n");
close(simpleSocket);
exit(1);
}
while (1)
{
struct sockaddr_in clientName = { 0 };
int simpleChildSocket = 0;
int clientNameLength = sizeof(clientName);
/* wait here */
simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);
if (simpleChildSocket == -1) {
fprintf(stderr, "Cannot accept connections!\n");
close(simpleSocket);
exit(1);
}
/* handle the new connection request */
/* write out our message to the client */
do {
read(simpleChildSocket, buff, 256);
num=atoi(buff);
conta++;
DT=(conta)-1;
DT=write(simpleChildSocket, buff, strlen(buff));
printf("Message received: %s\n", buff);
bzero(buff, 256);
} while(num!=0);
close(simpleChildSocket);
}
close(simpleSocket);
return 0;
}
There are some fixes in your code, especially on the client side. It is more convenient to send a package with |size| |data| at once, than each number.
The server side receives the packet, reads the size and accumulates, reads the data and accumulates and then sends size to the client.
If the client sends 0, the server calculates the average and sends the result.
I believe it will serve as the initial idea.
cliente side, main loop:
/*--------cliente side---------*/
int iResult;/*iResult >1 get from connect*/
char buffsend[256];
char szTmp[50];
do {
menset(buffsend,0,256);/*zero memory*/
menset(szTmp,0,50);/*zero memory*/
printf("insert num dati or terminate(write '0'): ");
fgets(szTmp,50,stdin);
int n = atoi(szTmp);
if(n>6)
printf("Error\n");
else
{
sprintf(buffsend,"%d ",n);
for(int h=0;h<n;h++)
{
printf("insert number: ");
fgets(szTmp,50,stdin);
szTmp[strcspn(szTmp, "\n")] = 0;/*<---remove end line */
strcat(buffsend,szTmp);/*concatenate new num*/
strcat(buffsend," ");/*add space*/
}
}
/*send the data <len><space><data> exemp: 2 12 34*/
iResult = write( ConnectSocket, buffsend, strlen(buffsend) );
if (iResult == -1)
{
printf("send failed with error: -1\n");
close(ConnectSocket);
return 1;
}
menset(buffsend,0,256);/*zero memory*/
iResult = read(ConnectSocket, buffsend, 256);
if ( iResult > 0 )
printf("Bytes received: %d > %s \n", iResult,recvbuf);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
server side loop:
/*-------------server side------------*/
int iResult;/*At this point iResult is greater than 0, by the return of connect*/
int nNumerator;
int den;/*Accumulate sizes*/
float faverage;
nNumerator=0;
den = 0;
faverage=0;
do
{
memset(recvbuf,0,256);
iResult = read(ClientSocket, recvbuf, recvbuflen);
if (iResult > 0)
{
char bufftmp[25];
int numpart;
int iTmp;
numpart =0;
iTmp =0;
memset(bufftmp,0,25);
printf("Bytes received: %d\n", iResult);
printf("%s\n",recvbuf);
/*Traverses all received datar ecvbuf and separates the accumulating size into den,
and then accumulates the data in nNumerator*/
for(int k=0;k<iResult;k++)
{
bufftmp[iTmp++]=recvbuf[k];
if(recvbuf[k]==' ')
{
if(!numpart)/*is numpart zero*/
{
bufftmp[iTmp]='\0';//make space null
numpart=atoi(bufftmp);
den+=numpart;/*acumalate to average*/
printf("lenght: %d\n",numpart);/*get only length*/
memset(bufftmp,0,25);
if(numpart==0)
{
/*go to average*/
faverage = (float)nNumerator/(float)den;
}
}
else/* if numparte > 0 get data*/
{
bufftmp[iTmp]='\0';
printf("%s ",bufftmp);
nNumerator+=atoi(bufftmp);/*save in to buffer of int´s*/
memset(bufftmp,0,25);
}
iTmp=0;
printf("\n");
}
}
memset(recvbuf,0,256);
if(numpart)/*if not zero, send length of data to client*/
sprintf(recvbuf,"%d",numpart);
else/*if not, send average*/
sprintf(recvbuf,"%d %f",den,faverage);
iResult = write( ClientSocket, recvbuf, strlen(recvbuf));
if (iResult == -1)
{
printf("send failed with error: -1\n");
close(ClientSocket);
return 1;
}
}
else if (iResult == 0)
printf("Connection closing...\n");
else
{
printf("recv failed with error: -1\n");
close(ClientSocket);
return 1;
}
}while (iResult > 0);

Resources