I'm studying sockets and client server communication with select. My problem is that at line 261 i get the Bad File Descriptor error and I have no idea why. The message on line 233 arrives to the client, in the one after (line 252) the client instead of receiving the size in bytes receives 0, and in the write after (line 261) I get the error. I'm really confused.
This is the SERVER
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define DIM_BUFF 100
#define max 10
#define mass(a, b) ((a) > (b) ? (a) : (b))
/********************************************************/
void gestore(int signo) {
int stato;
printf("esecuzione gestore di SIGCHLD\n");
wait(&stato);
}
/********************************************************/
//STRUTTURA DATI
typedef struct{
char Targa[max];
int Patente;
char Tipo[max];
char Folder[max];
}Prenotazione;
//REQUEST DATAGRAM
typedef struct{
char Targa[max];
int newPatente[max];
}Request;
int main(int argc, char **argv) {
//inizializziamo struttura
Prenotazione pren[3];
//dati mock
strcpy(pren[0].Targa,"ciao1");
pren[0].Patente=1234;
strcpy(pren[0].Tipo,"tipo1");
strcpy(pren[0].Folder,"prova1");
strcpy(pren[1].Targa,"ciao2");
pren[1].Patente=1234;
strcpy(pren[1].Tipo,"tipo2");
strcpy(pren[1].Folder,"prova2");
strcpy(pren[2].Targa,"ciao3");
pren[2].Patente=1234;
strcpy(pren[2].Tipo,"tipo3");
strcpy(pren[2].Folder,"prova3");
printf("struttura dati inizializzata!!\n");
int listenfd, connfd, udpfd, nready, maxfdp1;
const int on = 1;
FILE* fd_file;
char zero = '\0' ,Targa[max],fileName[20],path[128];
int buff[DIM_BUFF];
fd_set rset;
int len, nread, nwrite, num, port,count=0;
long size;
struct sockaddr_in cliaddr, servaddr;
Request *req = (Request *)malloc(sizeof(Request));
DIR *dir1;
struct dirent *dd1;
/* CONTROLLO ARGOMENTI ---------------------------------- */
if (argc != 2) {
printf("Error: %s port\n", argv[0]);
exit(1);
}
nread = 0;
while (argv[1][nread] != '\0') {
if ((argv[1][nread] < '0') || (argv[1][nread] > '9')) {
printf("porta non intero\n");
exit(2);
}
nread++;
}
port = atoi(argv[1]);
if (port < 1024 || port > 65535) {
printf("Porta scorretta...");
exit(2);
}
/* INIZIALIZZAZIONE INDIRIZZO SERVER ----------------------------------------- */
memset((char *)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(port);
printf("Server avviato\n");
/* CREAZIONE SOCKET TCP ------------------------------------------------------ */
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) {
perror("apertura socket TCP ");
exit(1);
}
printf("Creata la socket TCP d'ascolto, fd=%d\n", listenfd);
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
perror("set opzioni socket TCP");
exit(2);
}
printf("Set opzioni socket TCP ok\n");
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("bind socket TCP");
exit(3);
}
printf("Bind socket TCP ok\n");
if (listen(listenfd, 5) < 0) {
perror("listen");
exit(4);
}
printf("Listen ok\n");
/* CREAZIONE SOCKET UDP ------------------------------------------------ */
udpfd = socket(AF_INET, SOCK_DGRAM, 0);
if (udpfd < 0) {
perror("apertura socket UDP");
exit(5);
}
printf("Creata la socket UDP, fd=%d\n", udpfd);
if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
perror("set opzioni socket UDP");
exit(6);
}
printf("Set opzioni socket UDP ok\n");
if (bind(udpfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("bind socket UDP");
exit(7);
}
printf("Bind socket UDP ok\n");
/* AGGANCIO GESTORE PER EVITARE FIGLI ZOMBIE -------------------------------- */
signal(SIGCHLD, gestore);
/* PULIZIA E SETTAGGIO MASCHERA DEI FILE DESCRIPTOR ------------------------- */
FD_ZERO(&rset);
maxfdp1 = mass(listenfd, udpfd) + 1;
/* CICLO DI RICEZIONE EVENTI DALLA SELECT ----------------------------------- */
for (;;) {
FD_SET(listenfd, &rset);
FD_SET(udpfd, &rset);
if ((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {
if (errno == EINTR)
continue;
else {
perror("select");
exit(8);
}
}
//GESTIONE RICHIESTE CAMBIO NUMERO PATENTE--------------------
if (FD_ISSET(udpfd, &rset)) {
int result=-1;
printf("Server: ricevuta richiesta di cambio numero patente\n");
len = sizeof(struct sockaddr_in);
if (recvfrom(udpfd, req, sizeof(Request), 0, (struct sockaddr *)&cliaddr, &len) <
0) {
perror("recvfrom");
continue;
}
printf("targa: %s \n", req->Targa);
printf("nuovo numero patente: %s \n", req->newPatente);
for(int i=0;i<3 && result==-1;i++){
if(strcmp(req->Targa,pren[i].Targa)==0){
pren[i].Patente=*req->newPatente;
result=0;
}
}
printf("cambio numero patente effettuato!, invio risposta... \n");
if (sendto(udpfd, &result, sizeof(result), 0, (struct sockaddr *)&cliaddr, len) < 0) {
perror("sendto");
continue;
}
}//IF UDP
//GESTIONE RICHIESTE SCARICAMENTO IMMAGINI
if (FD_ISSET(listenfd, &rset)) {
printf("Ricevuta richiesta di get di un file\n");
len = sizeof(struct sockaddr_in);
if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len)) < 0) {
if (errno == EINTR)
continue;
else {
perror("accept");
exit(9);
}
}
if (fork() == 0) { /* processo figlio che serve la richiesta di operazione */
close(listenfd);
printf("Dentro il figlio, pid=%i\n", getpid());
char Fold[max];
int trovato=-1;
while ((nread = read(connfd, &Targa, sizeof(Targa))) > 0) {
printf("Server (figlio): targa richiesta: %s\n", Targa);
for(int i=0;i<3;i++){
if(strcmp(Targa,pren[i].Targa)==0){
strcpy(Fold,pren[i].Folder);
trovato=i;
}
}
if(trovato>=0){
dir1 = opendir(Fold);
while ((dd1 = readdir(dir1)) != NULL) {
if (strcmp(dd1->d_name, ".") != 0 && strcmp(dd1->d_name, "..") != 0) {
strcpy(fileName, dd1->d_name);
if (write(connfd, fileName,(strlen(fileName) + 1)) < 0) {
perror("Errore nell'invio del nome file\n");
continue;
}
path[0] = '\0'; //path reset
sprintf(path, "%s/%s", pren[trovato].Folder, dd1->d_name);
fd_file = fopen(path, "rb");
if (fd_file < 0) {
printf("ERRORE Apertura FILE\n");
}
fseek(fd_file, 0, SEEK_END);
size=ftell(fd_file);
fseek(fd_file, 0, SEEK_SET);
printf("le dimensioni sono: %ld" ,size);
//invio la dimensione
if (write(connfd, &size,sizeof(long))< 0) {
perror("Errore nell'invio della dimensione file\n");
exit(0);
}
/* lettura dal file (a blocchi) e scrittura sulla socket */
printf("Leggo e invio il file richiesto\n");
while (count<size) {
nread = fread(buff, sizeof(int), sizeof(buff),fd_file);
if (nwrite = write(connfd, buff, sizeof(buff)) < 0) {
perror("write");
break;
}
bzero(buff, sizeof(buff));
count=count+nread;
}
printf("Terminato invio file\n");
fclose(fd_file);
}
}//while DD1
strcpy(fileName,"fine");
if (write(connfd, fileName,(strlen(fileName) + 1)) < 0) {
perror("Errore nell'invio del nome file\n");
continue;
}
printf("Terminato invio di tutti i file\n");
closedir(dir1);
}//if trovato
else{
strcpy(fileName,"errore");
if (write(connfd, fileName,(strlen(fileName) + 1)) < 0) {
perror("Errore nell'invio del nome file\n");
continue;
}
}
}//while richieste
printf("Figlio TCP terminato, libero risorse e chiudo. \n");
close(connfd);
exit(0);
}//FORK
sleep(1);
close(connfd); //padre chiude la socket(non di ascolto)
}//IF TCP
}//for SELECT
}//main
this is the CLIENT
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define DIM_BUFF 100
#define LENGTH_FILE_NAME 20
int main(int argc, char *argv[]) {
int sd, nread, port,count=0;
char nome_file[LENGTH_FILE_NAME],Targa[10];
struct hostent *host;
struct sockaddr_in servaddr;
int c;
long size;
/* CONTROLLO ARGOMENTI ---------------------------------- */
if (argc != 3) {
printf("Error:%s serverAddress serverPort\n", argv[0]);
exit(1);
}
printf("Client avviato\n");
/* PREPARAZIONE INDIRIZZO SERVER ----------------------------- */
memset((char *)&servaddr, 0, sizeof(struct sockaddr_in));
servaddr.sin_family = AF_INET;
host = gethostbyname(argv[1]);
if (host == NULL) {
printf("%s not found in /etc/hosts\n", argv[1]);
exit(2);
}
nread = 0;
while (argv[2][nread] != '\0') {
if ((argv[2][nread] < '0') || (argv[2][nread] > '9')) {
printf("Secondo argomento non intero\n");
exit(2);
}
nread++;
}
port = atoi(argv[2]);
if (port < 1024 || port > 65535) {
printf("Porta scorretta...");
exit(2);
}
servaddr.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;
servaddr.sin_port = htons(port);
/* CREAZIONE E CONNESSIONE SOCKET (BIND IMPLICITA) ----------------- */
sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd < 0) {
perror("apertura socket ");
exit(3);
}
printf("Creata la socket sd=%d\n", sd);
if (connect(sd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) < 0) {
perror("Errore in connect");
exit(4);
}
printf("Connect ok\n");
//inizio ciclo richieste
printf("numero della targa o EOF: \n");
while (gets(Targa)) {
if (write(sd, Targa, (strlen(Targa) + 1)) < 0) {
perror("write");
continue;
}
printf("Richiesta della targa %s inviata... \n", Targa);
//ricezione nome file ogni volta
if (read(sd, &nome_file, sizeof(nome_file)) < 0) {
perror("read");
break;
}
while(strcmp(nome_file,"fine")!=0 ){
FILE* f;
printf("il nome del file: %s \n" ,nome_file);
if (read(sd, &size, sizeof(long)) < 0) {
perror("read");
break;
}
if(size==0){
printf("size 0");
exit(1);
}
printf("la size e': %ld" ,size);
f=fopen(nome_file,"wb");
while (count<size){
nread = read(sd, &c, 1);
fwrite(&c,sizeof(int),1,f);
count=count+nread;
}
fclose(f);
printf("immagine ricevuta\n");
if (read(sd, &nome_file, sizeof(nome_file)) < 0) {
perror("read");
break;
}
}
if(strcmp(nome_file,"fine")==0){
printf("tutte le immaigini ricevute\n");
printf("numero della targa o EOF: \n");
}
else{
printf("ERRORE PROTOCOLLO\n");
shutdown(sd, 0);
shutdown(sd, 1);
close(sd);
exit(0);
}
}//whilw
printf("\nClient: termino...\n");
shutdown(sd, 0);
shutdown(sd, 1);
close(sd);
exit(0);
}//main
I've literally tried everything but it doesn't seem to work.
Thanks for your time and sorry form my bad english.
Related
I have 3 services in C and I want they communicate toghether with a docker compose but I can't.
I tried with a two simples images and they connected but not in a docker compose.
The problem are the function connect(). He return -1 beaucause in the inet_addr(), I want to include the image who the message will be sent.
I use 3 images with gcc for to compile C files.
# FILE : service1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
//#define PORT_SERV 4443
#define PORT_CLI 4443
time_t t;
static void * client(){
int clientSocket, ret;
struct sockaddr_in serverAddr;
char buffer[256];
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket < 0) {
printf("[Client -] Error in Client Socket \n");
fflush(stdout);
exit(1);
}
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT_CLI);
serverAddr.sin_addr.s_addr = inet_addr("image1");
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
while (ret < 0) {
printf("[Client -] Erreur de connexion. Nouvel essai ! %d\n", ret);
fflush(stdout);
sleep(3);
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
}
printf("[Client +] Connected to Server.\n");
fflush(stdout);
while(1){
time(&t);
strcpy(buffer, "Bonjour depuis le service 1");
sleep(5);
send(clientSocket, buffer, strlen(buffer), 0);
if (strcmp(buffer, ": exit") == 0) {
printf("[Client -] Disconnected from server.\n");
fflush(stdout);
exit(1);
}
if (recv(clientSocket, buffer, 256, 0) < 0) {
printf("[Client -] Error in receiving data. \n");
fflush(stdout);
} else {
printf("%sService 1 : %s \n", ctime(&t), buffer);
fflush(stdout);
}
}
}
int main(void){
//pthread_t s,
pthread_t c;
int ret = 0;
ret = pthread_create(&c, NULL, &client, NULL);
/*ret = pthread_create(&s, NULL, &server, NULL);
if (! ret) {
ret = pthread_create(&c, NULL, &client, NULL);
}*/
//pthread_join(s, NULL);
pthread_join(c, NULL);
return 0;
}
FILE = service2.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define PORT_SERV 4442
#define PORT_CLI 4443
time_t t;
time_t t2;
static void * server(){
int sockfd, ret;
struct sockaddr_in serverAddr;
int newSocket;
struct sockaddr_in newAddr;
char buffer[256];
pid_t childpid;
socklen_t addr_size;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("[-] Error in Client Socket\n");
fflush(stdout);
exit(1);
}
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT_SERV);
serverAddr.sin_addr.s_addr = inet_addr("image1");
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if (ret < 0) {
printf("[-] Error in binding\n");
fflush(stdout);
exit(1);
}
printf("[+] Bind to port %d\n", PORT_CLI);
fflush(stdout);
if (listen(sockfd, 10) == 0) {
printf("[+] Listening...\n");
fflush(stdout);
} else {
printf("[-] Error in binding\n");
fflush(stdout);
}
while(1)
{
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
if(newSocket < 0) {
exit(1);
}
printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
fflush(stdout);
if ((childpid = fork()) == 0)
{
close(sockfd);
while (1)
{
time(&t2);
recv(newSocket, buffer, 256, 0);
if(strcmp(buffer, ": exit") == 0){
printf("Disconnected from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
fflush(stdout);
break;
} else {
printf("%sClient : %s\n", ctime(&t2), buffer);
fflush(stdout);
send(newSocket, buffer, strlen(buffer), 0);
bzero(buffer, sizeof(buffer));
}
}
}
}
close(newSocket);
}
static void * client(){
int clientSocket, ret;
struct sockaddr_in serverAddr;
char buffer[256];
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket < 0) {
printf("[-] Error in connection\n");
fflush(stdout);
exit(1);
}
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT_CLI);
serverAddr.sin_addr.s_addr = inet_addr("image3");
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
while (ret < 0) {
printf("[-] Erreur de connexion. Nouvelle tentative !\n");
fflush(stdout);
sleep(3);
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
}
printf("[+] Connected to Server.\n");
while(1){
time(&t);
strcpy(buffer, "Bonjour depuis le service 2");
sleep(5);
send(clientSocket, buffer, strlen(buffer), 0);
if (strcmp(buffer, ": exit") == 0) {
printf("[Client -] Disconnected from server.\n");
fflush(stdout);
exit(1);
}
if (recv(clientSocket, buffer, 256, 0) < 0) {
printf("[Client -] Error in receiving data. \n");
fflush(stdout);
} else {
printf("%sService 2: %s \n", ctime(&t), buffer);
fflush(stdout);
}
}
}
int main(void){
pthread_t s, c;
int ret = 0;
ret = pthread_create(&s, NULL, &server, NULL);
if (! ret) {
ret = pthread_create(&c, NULL, &client, NULL);
}
pthread_join(s, NULL);
pthread_join(c, NULL);
return 0;
}
FILE = service3.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define PORT_SERV 4444
//#define PORT_CLI 4443
time_t t;
time_t t2;
static void * server(){
printf("Hello World!\n");
int sockfd, ret;
struct sockaddr_in serverAddr;
int newSocket;
struct sockaddr_in newAddr;
char buffer[256];
pid_t childpid;
socklen_t addr_size;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("[-] Error in connection\n");
exit(1);
}
printf("[+] Client Socket is created !\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT_SERV);
serverAddr.sin_addr.s_addr = inet_addr("image2");
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if (ret < 0) {
printf("[-] Error in binding\n");
exit(1);
}
printf("[+] Bind to port %d\n", 4444);
if (listen(sockfd, 10) == 0) {
printf("[+] Listening...\n");
} else {
printf("[-] Error in binding\n");
}
while(1)
{
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
if(newSocket < 0) {
exit(1);
}
printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
fflush(stdout);
if ((childpid = fork()) == 0)
{
close(sockfd);
while (1)
{
time(&t2);
recv(newSocket, buffer, 256, 0);
if(strcmp(buffer, ": exit") == 0){
printf("Disconnected from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
} else {
printf("%sClient : %s\n", ctime(&t2), buffer);
send(newSocket, buffer, strlen(buffer), 0);
bzero(buffer, sizeof(buffer));
}
}
}
}
close(newSocket);
}
int main(void){
printf("Hello World!\n");
fflush(stdout);
pthread_t s;
//pthread_t c;
int ret = 0;
printf("Thread du server\n");
ret = pthread_create(&s, NULL, &server, NULL);
/*if (! ret) {
printf("Thread du client\n");
ret = pthread_create(&c, NULL, &client, NULL);
}*/
pthread_join(s, NULL);
//pthread_join(c, NULL);
return 0;
}
File = docker-compose.yml
version: "3.8"
services:
image1:
build: ./image1
image: service1:1.0
networks:
- mynet
ports:
- 127.0.0.1:4441:4441
image2:
build: ./image2
image: service2:1.0
networks:
- mynet
ports:
- 127.0.0.1:4442:4442
image3:
build: ./image3
image: service3:1.0
networks:
- mynet
ports:
- 127.0.0.1:4443:4443
networks:
mynet:
I build and run with docker compose build docker compose up -d and the images don't connect toghether.
Thanks !
I am writing a private chat using UDP, but I have some problems while implementing the registration service. When the client writes the ID and password he wants to use, the server checks if the ID already exists(IDs and password are saved in a file), if it doesn't exist yet, the client can start chatting with other users(I still haven't implemented this part), if the ID is already in use I want to tell the user to choose another ID. In this scenario, I send the message "ID already in use" to the client using sendto but the recvfrom sometimes riceives other messages. Precisely the first time the user chooses a wrong ID, he receives the right message, then, if he chooses again an ID already in use, from the message he has received from the server he reads the ID he tried to choose and not the error message.The strangest thing is that at a third wrong attempt, the error message is correct.
Messages and related functions are defined in a file called utils.h
typedef struct Message{
int type; //Message's type: 0->registration; 1->login; 2->message; 3->ack
char* dest;
char* mitt; //source
char msg[1024];
}Message;
//createMsg is used to fill message struct
int createMsg(int type, char* dest, char* mitt, char * msg, struct Message* message){ //char msg[1024]
//printf("Sono in createMsg\n");
memset(message,0,sizeof(*message));
message->type = type;
message->dest = dest;
message->mitt = mitt;
//printf("msg to write: %s\n",msg);
strcpy(message->msg,msg);
//printf("msg written: %s\n",message->msg);
}
//print messages
void printMsg(struct Message* message){
if(strlen(message->msg)!=0) printf("type: %d, dest: %s, mitt:%s, msg: %s\n",message->type,message->dest,message->mitt,message->msg);
printf("dim msg tot: %lu\n",sizeof(*message));
printf("type dim: %lu, dest dim: %lu, mitt dim:%lu, msg dim: %lu, dim tot msg: %lu\n",sizeof(message->type),sizeof(message->dest),sizeof(message->mitt),strlen(message->msg),sizeof(message->msg));
}
//Set message's field to zero
void setToZeroMsg(struct Message* message){
message->type = 0;
message->dest = NULL;
message->mitt = NULL;
int i=0;
for(i=0;i<strlen(message->msg);i++){
message->msg[i]=0;
}
//memset(message->msg,0,strlen(message->msg));
}
This is the server:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <arpa/inet.h> // htons()
#include <netinet/in.h> // struct sockaddr_in
#include <sys/socket.h>
//#include "utente.h"
#include "utils.h"
#define MAX_CONNECTIONS 5
#define MAX_MESSAGE 1024
int main(){
int sockfd, ret;
char buffer[MAX_MESSAGE];
size_t buf_len = sizeof(buffer);
struct sockaddr_in server_addr, client_addr;
int serv_addr_len = sizeof(server_addr);
int client_addr_len = sizeof(client_addr);
//socket file descriptor
sockfd = socket(AF_INET, SOCK_DGRAM,0);
if(sockfd < 0){
perror("Errore nel creare la socket!");
exit(EXIT_FAILURE);
}
//Setting structure's content to zero
memset(&server_addr,0,serv_addr_len);
memset(&client_addr,0,client_addr_len);
//Server addr
server_addr.sin_family = AF_INET; //IPv4
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(5500);
//Bind
ret = bind(sockfd, (const struct sockaddr *)&server_addr, serv_addr_len);
if(ret < 0){
perror("Errore nella bind!");
exit(EXIT_FAILURE);
}
struct Message* newmsg = (struct Message*)malloc(sizeof(struct Message));
//Start comunication with clients
//int num_clients = 0;
while(1){
setToZeroMsg(newmsg); //Cancel previous messages
printf("waiting for a message from a client...\n");
//Receiving a message
ret = recvfrom(sockfd, newmsg, sizeof(*newmsg), 0, (struct sockaddr*)&client_addr, &client_addr_len);
if(ret == -1){
perror("Errore nella recvfrom!");
}
printMsg(newmsg);
int type = newmsg->type;
if(type == 0){ //Type==0 -> register request
printf("register request\n");
int newID = 0; //if is set to -1 the ID already exist
size_t msg_len=sizeof(newmsg->msg);
FILE* file = fopen("utenti.txt","r+");
if(file==NULL){
perror("Errore nell'apertura del file");
}
char* newuser = strcpy(newser,newmsg->msg);
strtok(newuser,";");
int size_newuser = sizeof(newuser);
while(1){
char* res = fgets(buffer,32,file);
if(res==NULL) break;
//printf("%s",buffer);
char* user = strtok(buffer,";");
//printf("%s\n",user);
int size_user = sizeof(user);
int size = (size_newuser > size_user)? size_newuser : size_user;
if(strncmp(newuser,user,size) == 0){
//printf("This name is already in use!\n");
/*memset(newmsg,0,sizeof(Message));
newmsg->type = 3;
newmsg->dest = NULL;
strcpy(newmsg->msg, "This ID is already taken!\n");
printf("mess: %s",newmsg->msg);*/
//Error message to client
creaMsg(3, NULL, NULL, "This ID is already taken!\n", newmsg); //buffer
printMsg(newmsg);
printf("msg: %s\n",newmsg->msg);
//ret = sendto(sockfd, (struct Message*)newmsg, sizeof(*newmsg), 0, (struct sockaddr*)&client_addr, (socklen_t) client_addr_len);
ret = sendto(sockfd,newmsg->msg,sizeof(newmsg->msg),0,(struct sockaddr*)&client_addr, (socklen_t) client_addr_len );
if(ret == -1){
perror("Errore nella sendto!");
exit(EXIT_FAILURE);
}
newID = -1;
break;
}
}
if(newID != -1){
ret = fprintf(file,newmsg->msg,msg_len);
if(ret == -1){
perror("Errore nella scrittura su file");
}
}
if(fclose(file) == -1) perror("Errore nella chiusura del file");
}
else if(type==1){
}
else if(type==2){
}
//This part is not implemented yet
/*ret = sendto(sockfd, buffer, buf_len,0,(const struct sockaddr*)&client_addr, (socklen_t) client_addr_len);
if(ret == -1){
perror("Errore nella sendto!");
}*/
}
close(sockfd);
return 0;
}
And this is the client file:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <arpa/inet.h> // htons()
#include <netinet/in.h> // struct sockaddr_in
#include <sys/socket.h>
//#include "utente.h"
#include "utils.h"
#define MAX_MESSAGE 1024
#define quit_command "QUIT"
int main(){
int sockfd, ret;
struct sockaddr_in server_addr;
int serv_addr_len = sizeof(server_addr);
char buffer[MAX_MESSAGE];
size_t buf_len = sizeof(buffer);
size_t msg_len;
int quit_command_len = strlen(quit_command);
//Message struct
struct Message message = {};
setToZeroMsg(&message);
//socket file descriptor
sockfd = socket(AF_INET, SOCK_DGRAM,0);
if(sockfd < 0){
perror("Errore nel creare la socket!");
exit(EXIT_FAILURE);
}
//Structures to zero
memset(&server_addr,0,serv_addr_len);
//Initialize server_addr
server_addr.sin_family = AF_INET; //IPv4
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(5500);
printf("Welcome in Private Chat!\n");
while(1){
char buf_credentials[32];
memset(buf_credentials,0,sizeof(buf_credentials));
memset(buffer,0,sizeof(buffer));
//setToZeroMsg(&message);
printf("If you want to register write 'r', to login type 'l':\n");
if (fgets(buffer, MAX_MESSAGE, stdin) != (char*)buffer) {
fprintf(stderr, "Error while reading from stdin, exiting...\n");
exit(EXIT_FAILURE);
}
if(!memcmp(buffer, "l", 1)){
printf("not implemented yet");
break;
}
else if(!memcmp(buffer,"r",1)){
printf("To register choose an ID and a password.\n");
printf("ID:\n");
if (fgets(buffer, 15, stdin) != (char*)buffer) {
fprintf(stderr, "Error while reading from stdin, exiting...\n");
exit(EXIT_FAILURE);
}
//printf("%s\n",buffer);
strncpy(buf_credentials,buffer,strlen(buffer)-1);
strcat(buf_credentials,";");
printf("Inserire password:\n");
if (fgets(buffer, 15, stdin) != (char*)buffer) {
fprintf(stderr, "Error while reading from stdin, exiting...\n");
exit(EXIT_FAILURE);
}
strcat(buf_credentials,buffer);
printf("utente+pass: %s",buf_credentials);
//Message struct
/*
struct Message message = {
};*/
setToZeroMsg(&message);
strcpy(message.msg, buf_credentials);
//send ID e password to server
ret = sendto(sockfd, (struct Message*)&message, sizeof(message), 0, (struct sockaddr*)&server_addr, (socklen_t) serv_addr_len);
if(ret == -1){
perror("Errore nella sendto!");
continue;
}
setToZeroMsg(&message);
printf("msg: %s\n",message.msg);
//ret = recvfrom(sockfd, (struct Message*)&message, sizeof(message), 0, (struct sockaddr*)&server_addr, (socklen_t*)&serv_addr_len);
ret = recvfrom(sockfd, message.msg, sizeof(message.msg), 0, (struct sockaddr*)&server_addr, (socklen_t*)&serv_addr_len);
printMsg(&message);
printf("msg: %s\n",message.msg);
if(ret == -1){
perror("Errore nella recvfrom!");
}
continue;
}
else{ //User didn't type 'r' or 'l'
printf("Wrong, you have to type 'r' o 'l'\n");
}
memset(buffer,0,MAX_MESSAGE);
}
//Chatting with server
while(1){
memset(buffer,0,MAX_MESSAGE);
printf("Type the message for the server, QUIT to leave the chat:\n");
if (fgets(buffer, MAX_MESSAGE, stdin) != (char*)buffer) {
fprintf(stderr, "Error while reading from stdin, exiting...\n");
exit(EXIT_FAILURE);
}
printf("You wrote: %s\n", buffer);
msg_len=strlen(buffer);
//Send Message
ret = sendto(sockfd, buffer, MAX_MESSAGE, 0, (struct sockaddr*)&server_addr, (socklen_t) serv_addr_len);
if(ret == -1){
perror("Errore nella sendto!");
continue;
}
//Server wrote back
memset(buffer,0,MAX_MESSAGE);
ret = recvfrom(sockfd, buffer, buf_len, 0, (struct sockaddr*)&server_addr, &serv_addr_len);
if(ret == -1){
perror("Errore nella recvfrom!");
}
printf("Message received from server: %s\n",buffer);
//Controlla se il messaggio ricevuto รจ QUIT
if (msg_len == quit_command_len+1 && !memcmp(buffer, quit_command, quit_command_len)) break;
}
printf("Closing connection!\n");
close(sockfd);
return 0;
}
ID and password are stored in the file "utenti.txt", separated by semicolons, in this way:
ID1;password1
ID2;password2
...
I hope I have been clear about my problem, thank you for helping me!
I googled and stack-overflowed a lot but didn't find any solution. I have a simple echo client-server program in which client sends a word and the server echoes it.
This is my server.c file:
#define PORT 4444
#define MAX_CONNESSIONI 100
int main ()
{
int serverSocket, bindStatus;
struct sockaddr_in serverAddress;
int clientSocket;
struct sockaddr_in newAddress;
char buffer[1024];
pid_t child;
socklen_t addrSize;
ssize_t nread;
// Creazione della socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == -1) {
perror("[-]Errore durante la creazione della socket\n");
exit(-1);
}
printf("[+]Echo-Server socket has been created\n");
memset(&serverAddress, '\0', sizeof(serverAddress));
// Riempimento dei campi della struct
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(PORT);
serverAddress.sin_addr.s_addr = INADDR_ANY;
// Binding della socket all'indirizzo specificato. Associa alla socket un indirizzo in modo da poter essere contattata dai client
if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1) {
perror("[-]Errore durante il binding\n");
exit(1);
}
printf("[+]Bind to port %d\n", PORT);
// Imposta la socket all'ascolto. I parametri sono il descrittore della socket e la massima lunghezza della coda di connessioni entranti
if (listen(serverSocket, MAX_CONNESSIONI) != -1) {
printf("Listening . . .\n\n");
}
else {
perror("[-]Error during listening\n");
exit(1);
}
while (1) {
// Accettazione della connessione
clientSocket = accept(serverSocket, (struct sockaddr*)&newAddress, &addrSize);
if (clientSocket == -1) {
exit(-1);
}
printf("%s:%d joined\n", inet_ntoa(newAddress.sin_addr), ntohs(newAddress.sin_port));
child = fork();
if (child == 0) {
close(serverSocket);
while (1) {
// Ricezione del messaggio
if ( (nread=recv(clientSocket, buffer, sizeof buffer - 1, 0)) <= 0) {
perror("[-]Error in receiving data from server\n");
}
else {
buffer[nread] = '\0';
}
if (strcmp(buffer, ":exit") == 0) {
printf("%s:%d left\n", inet_ntoa(newAddress.sin_addr), ntohs(newAddress.sin_port));
break;
}
else {
printf("%s:%d wrote: %s\n", inet_ntoa(newAddress.sin_addr), ntohs(newAddress.sin_port), buffer);
// Invio del messaggio
send(clientSocket, buffer, strlen(buffer), 0);
bzero(buffer, sizeof(buffer));
}
}
}
}
close(clientSocket);
return 0;
}
you can compile it using
gcc -o server.out server.c
and execute it using
./server.out
and this is my client.c file:
#define PORT 4444
int main ()
{
int clientSocket;
struct sockaddr_in serverAddress;
char buffer[1024];
ssize_t nread;
// Creazione della socket
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == -1) {
perror("[-]Errore durante la creazione della socket\n");
exit(-1);
}
printf("[+]Client socket has been created\n");
memset(&serverAddress, '\0', sizeof(serverAddress));
// Riempimento dei campi della struct
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(PORT);
serverAddress.sin_addr.s_addr = INADDR_ANY;
// Connessione
if (connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1) {
perror("Errore con la connessione\n");
exit(-1);
}
printf("[+]Connected to Server\n");
printf("[+]Use single-word and :exit to logout\n");
while (1) {
printf("> ");
//fgets(buffer, 1024, stdin); Per ottenere una stringa con gli spazi
fflush(stdin);
scanf("%s", buffer);
// Invio dei dati al server
if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
perror("Errore con l'invio");
exit(1);
}
// Per uscire dalla connessione
if(strcmp(buffer, ":exit") == 0) {
close(clientSocket);
printf("[-]Disconnected from Server\n");
exit(0);
}
// Riceve i dati dal server
if ( (nread=recv(clientSocket, buffer, sizeof buffer - 1, 0)) <= 0) {
perror("[-]Error in receiving data from server\n");
}
else {
buffer[nread] = '\0';
printf("Server received: %s\n", buffer);
}
}
close(clientSocket);
return 0;
}
you can compile it using gcc -o client.out client.c
and execute it using ./client.out
This works fine.
How can I edit so that I can execute the server on two different computers?
Change INADDR_ANY to your server IP address.
serverAddress.sin_addr.s_addr = inet_addr("192.168.1.20");
I'm trying to create a communication between two processes after a fork, thus between a father process and a son process. I'm trying to use sockets with PF_UNIX and AF_UNIX families, but when I try to send a message, the error "transmission endpoint not connected" occurs. I don't really understand where my error is.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/un.h>
#define PATH "/tmp/Server"
int main() {
pid_t proc1, proc2;
proc1 = fork();
if(proc1 == -1) {
printf("Errore nella prima fork\n");
exit(0);
}
if(proc1 != 0) {
//PADRE DOPO IL PRIMO FIGLIO
//Lo stesso procedimento si fa per il secondo figlio
proc2 = fork();
if(proc2 == -1) {
printf("Errore nella prima fork\n");
exit(0);
}
wait(NULL); //Attesa che UN figlio termini
if(proc2 != 0) {
//PADRE DOPO I DUE FIGLI
unlink(PATH);
int father_desc = socket(PF_UNIX, SOCK_STREAM, 0);
int son1_desc;
struct sockaddr_un father_add = {AF_UNIX, PATH};
struct sockaddr_un son1_add;
if(-1 == bind(father_desc, (struct sockaddr*)&father_add, sizeof(struct sockaddr))) {
perror("Errore nel bind");
close(father_desc);
close(son1_desc);
wait(NULL);
exit(0);
}
if(-1 == listen(father_desc, 2)) {
perror("Errore nel listen");
close(father_desc);
close(son1_desc);
wait(NULL);
exit(0);
}
int len = sizeof(son1_add);
son1_desc = accept(father_desc, (struct sockaddr*)&son1_add, &len);
if(-1 == son1_desc) {
perror("Errore nell'accept");
close(father_desc);
close(son1_desc);
wait(NULL);
exit(0);
}
char message[256] = "Ciao";
if(-1 == send(father_desc, message, strlen(message) + 1, 0)) {
perror("Errore nel send"); /* -> ERROR HERE */
close(father_desc);
close(son1_desc);
wait(NULL);
exit(0);
}
close(father_desc);
close(son1_desc);
wait(NULL);
} else {
//SECONDO FIGLIO
}
} else {
//PRIMO FIGLIO
sleep(1);
struct sockaddr_un son1_add = {AF_UNIX, PATH};
int son1_desc = socket(PF_UNIX, SOCK_STREAM, 0);
if(-1 == connect(son1_desc, (struct sockaddr*) &son1_add, sizeof(struct sockaddr))) {
perror("Errore nel connect");
shutdown(son1_desc, SHUT_RDWR);
close(son1_desc);
exit(0);
}
char message[256] = "";
if(-1 == recv(son1_desc, message, strlen(message) + 1, 0)) {
perror("Errore nel rcv");
shutdown(son1_desc, SHUT_RDWR);
close(son1_desc);
wait(NULL);
exit(0);
}
printf("%s\n", message);
shutdown(son1_desc, SHUT_RDWR);
close(son1_desc);
}
return 0;
}
You want to call send on the accepted socket not on the listening socket.
So this
if(-1 == send(father_desc, message, strlen(message) + 1, 0)) {
should be
if(-1 == send(son1_desc, message, strlen(message) + 1, 0)) {
Aside of this there are other issues:
len should be socklen_t not int.
The client part fails to check if the call to socket() succeeded.
strlen() on an empty string returns 0.
Transmission on endpoint 2 failures (on ICD-3) point you at the target board complaining about `voltages'. This is wrong. Its a usb driver permissions error (well on Linux)
this fixes it
$ cd /dev/bus/usb
$ sudo chmod 777 *
I have a simply program with server and client that comunicate with AF_STREAM socket.
Client will can send multiple request to server, and the server response with a string but I don't know the lenght. The client stops in reading when read return 0 and restarts after the server stops the comunication. I don't understand why.
//SEVER
int main(void){
int idSockServer, idSockClient, clientLen;
struct sockaddr_in indirizzoClient, indirizzoServer;
unsigned short richiesta = 0;
char nomeFile[L_STRING], buffer[L_BUFFER];
printf("Inizializzaione del server\n");
idSockServer = socket(AF_INET, SOCK_STREAM, 0);
if(idSockServer == -1){
fprintf(stderr, "Errore socket\n");
exit(EXIT_FAILURE);
}
indirizzoServer.sin_addr.s_addr = htonl(INADDR_ANY);
indirizzoServer.sin_port = htons(5566);
indirizzoServer.sin_family = AF_INET;
if(bind(idSockServer, (struct sockaddr *) &indirizzoServer, sizeof(indirizzoServer))){
fprintf(stderr, "Errore bind\n");
exit(EXIT_FAILURE);
}
if(listen(idSockServer, 5) == -1){
fprintf(stderr, "Errore listen\n");
exit(EXIT_FAILURE);
}
while(1){
printf("[SERVER] Pronto!\n");
clientLen = sizeof(indirizzoClient);
idSockClient = accept(idSockServer, (struct sockaddr *) &indirizzoClient, &clientLen);
if(idSockClient == -1){
printf("[SERVER] Errore alla connessione\n");
continue;
}
read(idSockClient, &richiesta, L_BUFFER);
switch(richiesta){
case 1:
printf("[SERVER] Richiesta 1 accetata, invio risposta\n");
//this simulates the variable lenght string
strcpy(buffer, "un file\n");
write(idSockClient, buffer, L_BUFFER);
break;
}
sleep(6);
close(idSockClient);
}
}
Here the client
//CLIENT
int main(void) {
int sockIdClient, clientLen, file, len;
char buffer[L_BUFFER], nomeFile[L_STRING];
struct sockaddr_in indirizzoClient;
unsigned short scelta, risposta = 0;
sockIdClient = socket(AF_INET, SOCK_STREAM, 0);
if (sockIdClient == -1) {
perror("Errore creazione socket");
exit(EXIT_FAILURE);
}//fine if creazione socket
indirizzoClient.sin_addr.s_addr = htonl(INADDR_ANY);
indirizzoClient.sin_family = AF_INET;
indirizzoClient.sin_port = htons(5566);
if (connect(sockIdClient, (struct sockaddr *) &indirizzoClient, sizeof (indirizzoClient)) == -1) {
perror("Errore connessione al server");
exit(EXIT_FAILURE);
}//fine connect
do {
printf("1) File disponibili\n");
printf("2) Scarica file\n");
printf("0) Esci\n");
printf("Scelta --> ");
scanf("%hu", &scelta);
switch (scelta) {
case 1:
write(sockIdClient, &scelta, sizeof (unsigned short));
len = read(sockIdClient, buffer, L_BUFFER);
while (len > 0) {
printf("%s", buffer);
printf("%d\n", len);
len = read(sockIdClient, buffer, len);
}
break;
case 2:
//This part of code is not managed by Server yet
write(sockIdClient, &scelta, sizeof (unsigned short));
read(sockIdClient, &risposta, sizeof (int));
if (risposta) {
printf("Nome file: ");
leggiStringa(nomeFile, L_STRING);
write(file = sockIdClient, nomeFile, L_STRING);
if (open(nomeFile, O_WRONLY | O_CREAT, "0666") == -1) {
perror("Errore apertura del file");
close(sockIdClient);
exit(EXIT_FAILURE);
}//fine open
len = read(sockIdClient, buffer, L_BUFFER);
while (len > 0) {
write(file, buffer, L_BUFFER);
printf("leggo..\n");
len = read(sockIdClient, buffer, len);
}
close(file);
} else printf("Il server non ha accetato la richiesta\n");
break;
default:
printf("Scelta non valida");
}
} while (scelta != 0);
close(sockIdClient);
}