Ciao Ananke Melior,
si, in trasmissione puoi usare la stessa tecnica, ma dipende sempre da quello che devi trasmettere. Se abbiamo una stringa, la send la spedisce interamente. Se abbiamo un file, leggiamo il block e lo spediamo fino a fine file (iteriamo fino a FF).
Qualora avessimo un input della stringa, il buffer di tastiera ti viene d'aiuto.Osserva questo giro:
...
for (;;)
{
fgets (block, BLOCK_SIZE, stdin);
if ((len=send(sock, block,strlen(block),0))<1)
break;
if (strcmp(block,"EXIT\n")==0)
break;
}
...
La
fgets accetta al massimo
BLOCK_SIZE caratteri, ma se sforiamo la dimensione provvede a leggere il resto dal buffer di tastiera e questo potrebbe essere un grande aiuto che il sistema ti offre gratuitamente.
Per darti un esempio ti ho scritto una versione client. Non far caso a come vado a prendermi l'indirizzo di connessione... se vuoi approfondire leggi il manuale ($man 3p getaddrinfo).
include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define BLOCK_SIZE 8
#define FAMILY AF_INET
#define PORT 7777
/** get sockaddr, IPv4 or IPv6 */
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main (int argc, char **argv)
{
int sock,x;
struct addrinfo hints,*servinfo, *p;
char host_addr[INET6_ADDRSTRLEN];
char port[16];
ssize_t len;
char block[BLOCK_SIZE];
if (argc!=2)
{
fprintf (stderr, "Usage:\t%s host\n",argv[0]);
return -1;
}
snprintf (port,sizeof(port),"%d",PORT);
memset(&hints, 0, sizeof (hints));
hints.ai_family =FAMILY;
hints.ai_socktype = SOCK_STREAM;
if ((x=getaddrinfo(argv[1], port, &hints, &servinfo)) != 0)
{
fprintf (stderr,"getaddrinfo: %s\n", gai_strerror(x));
return -1;
}
for(p=servinfo;p;p=p->ai_next)
{
if ((sock=socket(p->ai_family, p->ai_socktype, p->ai_protocol))<0)
{
perror("Warning: socket");
continue;
}
inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), host_addr, sizeof (host_addr));
printf ("try connecting to %s port %s...\n",host_addr,port);
if ((connect(sock, p->ai_addr, p->ai_addrlen))<0)
{
perror ("Warning: connect");
continue;
}
printf ("Good one. Done\n");
break;
}
for (;;)
{
fgets (block, BLOCK_SIZE, stdin);
if ((len=send(sock, block,strlen(block),0))<1)
break;
if (strcmp(block,"EXIT\n")==0)
break;
}
if (len<0)
perror ("send");
else if (len==0)
printf ("connection closed by peer. Bye!\n");
else
printf ("connection closed\n");
freeaddrinfo(servinfo);
close (sock);
return 0;
}
Uso a scopo dimostrativo sempre lo stesso block sottodimensionato sempre ad 8 caratteri (8 byte) appositamente per scopo didattico.
Per l'esecuzione mi riappoggio a
netcat, in modalità
listen, sempre sulla porta 7777. Ora uso 2 terminali:
term1
max@studio:~> nc -l localhost -p 7777
term2
max@studio:~> gcc prova.c -Wall
max@studio:~> valgrind --leak-check=full ./a.out localhost
NB: decido di usare
valgrind per verificare se vi sono errori per quello che andrò a fare
term2
max@studio:~> valgrind --leak-check=full ./a.out localhost
==4896== Memcheck, a memory error detector
==4896== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4896== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==4896== Command: ./a.out localhost
==4896==
try connecting to 127.0.0.1 port 7777...
Good one. Done
... in un altro ti svegli e devi cominciare da zero
EXIT
connection closed
==4896==
==4896== HEAP SUMMARY:
==4896== in use at exit: 0 bytes in 0 blocks
==4896== total heap usage: 10 allocs, 10 frees, 1,696 bytes allocated
==4896==
==4896== All heap blocks were freed -- no leaks are possible
==4896==
==4896== For counts of detected and suppressed errors, rerun with: -v
==4896== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
max@studio:~>
term1
max@studio:~> nc -l localhost -p 7777
... in un altro ti svegli e devi cominciare da zero
EXIT
max@studio:~>
Come puoi osservare,
valgrind non ci segnala nessuno sforamento! Eppure abbiamo scritto un input lungo su un buffer di più piccolo.
Saluti,
Max