TCP Client connecting to two TCP Servers - c

This is the code of one of the TCP servers (it's also an UDP client but that should not matter) and we call it FS
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
int max(int fd, int fd2){
if(fd > fd2) return fd;
else return fd2;
int main(int argc, char *argv[]){
int ASfd, errcode, listenfd, User_fd;
ssize_t n;
socklen_t addrlen, addrlen2;
struct addrinfo hints, hints2, *res, *res2;
struct sockaddr_in addr;
struct sockaddr_in addr2;
fd_set readfds;
int pid;
char* AS_PORT = argv[3];
char* AS_IP = argv[2];
char* FS_PORT = argv[1];
char buffer[364];
char check[4], num_aluno[6], Fname[64], Fcontent[128];
long Fsize;
//TCP SOCKET
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == -1) exit(1);
memset(&hints2,0,sizeof hints2);
hints2.ai_family=AF_INET;
hints2.ai_socktype=SOCK_STREAM;
hints2.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(NULL,FS_PORT,&hints2,&res2);
if(errcode != 0){
perror("getaddrinfo");
exit(1);
}
n=bind(listenfd,res2->ai_addr, res2->ai_addrlen);
if(n==-1) exit(1);
if(listen(listenfd,10) == -1) exit(1);
ASfd = socket(AF_INET,SOCK_DGRAM,0);
if(ASfd==-1) exit(1);
memset(&hints,0,sizeof hints);
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(AS_IP,AS_PORT,&hints,&res);
if(errcode != 0) exit(1);
addrlen=sizeof(addr);
addrlen2=sizeof(addr2);
while(1){
FD_CLR(ASfd,&readfds);
FD_CLR(listenfd,&readfds);
FD_SET(ASfd,&readfds);
select(max(ASfd,listenfd)+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(ASfd,&readfds)){
n = recvfrom(ASfd,buffer,128,0,(struct sockaddr*)&addr,&addrlen);
if(n == -1) exit(1);
write(1,buffer,strlen(buffer)+1);
}
else if(FD_ISSET(listenfd,&readfds)){
User_fd = accept(listenfd,(struct sockaddr*)&addr2,&addrlen2);
if(User_fd == -1){
perror("accept");
exit(1);
}
if ((pid = fork())==0) {
close(listenfd);
while(1){
read(User_fd,buffer,364);
write(1,buffer,strlen(buffer)+1);
sscanf(buffer,"%s",check);
if(strcmp(check,"UPL")==0){
sscanf(buffer,"%s %s %s %ld %s",check,num_aluno,Fname,&Fsize,Fcontent);
write(1,Fcontent,strlen(Fcontent)+1);
}
}
freeaddrinfo(res);
close(User_fd);
exit(0);
}
}
}
}
This is the code of our second TCP server (it's also an UDP server) and we call it AS
int main(){
int fd, errcode, listenfd, newfd;
ssize_t n;
socklen_t addrlen, addrlen2;
struct addrinfo hints, hints2, *res, *res2;
struct sockaddr_in addr;
struct sockaddr_in addr2;
char buffer[128], buffertroll[128];
fd_set readfds;
int status = 0, rid, vc, new_vc = 0, pid, tid;
char Fop;
char check[4], password[9], num_aluno_s[6], PD_IP[64], PD_PORT[6], path[64], Fname[64];
//TCP SOCKET
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == -1) exit(1);
memset(&hints2,0,sizeof hints2);
hints2.ai_family=AF_INET;
hints2.ai_socktype=SOCK_STREAM;
hints2.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(NULL,PORT,&hints2,&res2);
if(errcode != 0) exit(1);
n=bind(listenfd,res2->ai_addr, res2->ai_addrlen);
if(n==-1) exit(1);
if(listen(listenfd,10) == -1) exit(1);
//UDP SOCKET (PD)
fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd==-1) exit(1);
memset(&hints,0,sizeof hints);
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(NULL,PORT,&hints,&res);
if(errcode != 0) exit(1);
n=bind(fd,res->ai_addr, res->ai_addrlen);
if(n==-1) exit(1);
mkdir("Users",0777);
addrlen=sizeof(addr);
addrlen2=sizeof(addr2);
while(1){
FD_CLR(fd,&readfds);
FD_SET(fd,&readfds);
FD_SET(listenfd,&readfds);
select(max(fd,listenfd)+1,&readfds,NULL,NULL,NULL);
/* PD communication */
if(FD_ISSET(fd,&readfds)){
memset(buffer,0,128);
memset(check,0,4);
n=recvfrom(fd,buffer,128,0,(struct sockaddr*)&addr,&addrlen);
if(n==-1) exit(1);
write(1,buffer,strlen(buffer)+1);
sscanf(buffer,"%s %s %s %s %s",check,num_aluno_s,password,PD_IP,PD_PORT);
/* case "register" message */
if(strcmp(check,"REG")==0){
write(1,"PD: new user, UID=",19);
write(1,num_aluno_s,6);
write(1,"\n",1);
sprintf(path,"Users/%s",num_aluno_s);
mkdir(path,0777);
createPassFile(num_aluno_s,password);
createRegFile(num_aluno_s,PD_IP,PD_PORT);
n = sendto(fd,"RRG OK\n",8,0,(struct sockaddr*)&addr,addrlen);
if(n == -1) exit(1);
}
/* case "exit" message */
if(strcmp(check,"UNR")==0){
sscanf(buffer,"%s %s %s",check,num_aluno_s,password);
memset(buffer,0,128);
status = deleteUser(num_aluno_s, password);
if (status) sprintf(buffer, "RUN OK\n");
else sprintf(buffer, "RUN NOK\n");
n = sendto(fd,buffer,strlen(buffer)+1,0,(struct sockaddr*)&addr,addrlen);
if(n == -1) exit(1);
}
}
/* User communication */
else if(FD_ISSET(listenfd,&readfds)){
newfd = accept(listenfd,(struct sockaddr*)&addr2,&addrlen2);
if(newfd == -1){
perror("accept");
exit(1);
}
if ((pid = fork())==0) {
close(listenfd);
while(1) {
memset(buffer,0,128);
memset(check,0,4);
read(newfd,buffer,128);
write(1,buffer,strlen(buffer)+1);
sscanf(buffer,"%s",check);
if(strcmp(check,"LOG")==0){
sscanf(buffer,"%s %s %s",check,num_aluno_s,password);
memset(buffer,0,128);
status = verifyUser(num_aluno_s, password);
if (status == 1){
sprintf(buffer,"User: login ok, UID=%s",num_aluno_s);
write(1,buffer,strlen(buffer)+1);
memset(buffer,0,128);
sprintf(buffer, "RLO OK\n");
createLogFile(num_aluno_s);
}
else if (status == 0) sprintf(buffer, "RLO NOK\n");
else sprintf(buffer, "ERR\n");
write(newfd,buffer,strlen(buffer)+1);
}
else if (strcmp(check,"REQ")==0){
sscanf(buffer,"%s %s %d %c %s",check,num_aluno_s,&rid,&Fop,Fname);
memset(buffer,0,128);
status = verifyLogin(num_aluno_s);
if (status) {
new_vc = getVC();
if (Fop == 'R' || Fop == 'U' || Fop == 'D') {
sprintf(buffer,"VLC %s %04d %c %s\n", num_aluno_s, new_vc, Fop, Fname);
sprintf(buffertroll,"User: upload req, UID=%s file: %s, RID=%d VC=%04d\n",num_aluno_s,Fname,rid,new_vc);
write(1,buffertroll,strlen(buffertroll)+1);
if (sendto(fd,buffer,strlen(buffer)+1,0,(struct sockaddr*)&addr,addrlen) == -1){
write(newfd,"RRQ EPD\n",9);
}
}
else if (Fop == 'L' || Fop == 'X') {
sprintf(buffer,"VLC %s %04d %c\n", num_aluno_s, new_vc, Fop);
if (sendto(fd,buffer,strlen(buffer)+1,0,(struct sockaddr*)&addr,addrlen) == -1)
write(newfd,"RRQ EPD\n",9);
}
else write(newfd,"RRQ EFOP\n",10);
} else write(newfd,"RRQ ELOG\n",10);
}
else if (strcmp(check,"AUT")==0){
sscanf(buffer,"%s %s %d %d", check, num_aluno_s, &rid, &vc);
if (new_vc == vc){
tid = getVC();
memset(buffertroll,0,128);
sprintf(buffertroll,"User: UID=%s %c, %s, TID=%04d\n",num_aluno_s,Fop,Fname,tid);
write(1,buffertroll,strlen(buffertroll)+1);
memset(buffertroll,0,128);
sprintf(buffertroll,"RAU %04d\n",tid);
write(newfd,buffertroll,strlen(buffertroll)+1);
createTIDFile(Fop,Fname,tid,num_aluno_s);
}
}
else if(strcmp(check,"EXT")==0){
memset(buffertroll,0,128);
if(deleteLogFile(num_aluno_s)==0){
write(newfd,"EXT NOK\n",8);
continue;
}
deleteTIDFile(num_aluno_s);
write(newfd,"EXT OK\n",7);
break;
}
}
freeaddrinfo(res);
close(newfd);
exit(0);
}
}
memset(num_aluno_s,0,6);
memset(password,0,9);
}
freeaddrinfo(res);
close(fd);
return 0;
}
This is the code used to connect to both TCP servers
//AS Connection
fd = socket(AF_INET,SOCK_STREAM,0);
if(fd==-1) exit(1);
memset(&hints,0,sizeof hints);
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_STREAM;
errcode = getaddrinfo(AS_IP,AS_PORT,&hints,&res);
if(errcode != 0) exit(1);
n = connect(fd,res->ai_addr,res->ai_addrlen);
if(n==-1) exit(1);
//FS Connection
FSfd = socket(AF_INET,SOCK_STREAM,0);
if(FSfd==-1) exit(1);
memset(&hints2,0,sizeof hints2);
hints2.ai_family=AF_INET;
hints2.ai_socktype=SOCK_STREAM;
errcode = getaddrinfo(FS_IP,FS_PORT,&hints2,&res2);
if(errcode != 0){
perror("lmao");
exit(1);
}
n = connect(FSfd,res2->ai_addr,res2->ai_addrlen);
if(n==-1) exit(1);
Right now our client works fine with AS but we can't connect with FS (accept never accepts any connection and it's blocked there) and I can't figure out what I am doing wrong.

FS Code needs to be like this
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
int max(int fd, int fd2){
if(fd > fd2) return fd;
else return fd2;
int main(int argc, char *argv[]){
int ASfd, errcode, listenfd, User_fd;
ssize_t n;
socklen_t addrlen, addrlen2;
struct addrinfo hints, hints2, *res, *res2;
struct sockaddr_in addr;
struct sockaddr_in addr2;
fd_set readfds;
int pid;
char* AS_PORT = argv[3];
char* AS_IP = argv[2];
char* FS_PORT = argv[1];
char buffer[364];
char check[4], num_aluno[6], Fname[64], Fcontent[128];
long Fsize;
//TCP SOCKET
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == -1) exit(1);
memset(&hints2,0,sizeof hints2);
hints2.ai_family=AF_INET;
hints2.ai_socktype=SOCK_STREAM;
hints2.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(NULL,FS_PORT,&hints2,&res2);
if(errcode != 0){
perror("getaddrinfo");
exit(1);
}
n=bind(listenfd,res2->ai_addr, res2->ai_addrlen);
if(n==-1) exit(1);
if(listen(listenfd,10) == -1) exit(1);
ASfd = socket(AF_INET,SOCK_DGRAM,0);
if(ASfd==-1) exit(1);
memset(&hints,0,sizeof hints);
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(AS_IP,AS_PORT,&hints,&res);
if(errcode != 0) exit(1);
addrlen=sizeof(addr);
addrlen2=sizeof(addr2);
while(1){
FD_CLR(ASfd,&readfds);
FD_CLR(listenfd,&readfds);
FD_SET(ASfd,&readfds);
FD_SET(listenfd,&readfds);
select(max(ASfd,listenfd)+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(ASfd,&readfds)){
n = recvfrom(ASfd,buffer,128,0,(struct sockaddr*)&addr,&addrlen);
if(n == -1) exit(1);
write(1,buffer,strlen(buffer)+1);
}
else if(FD_ISSET(listenfd,&readfds)){
User_fd = accept(listenfd,(struct sockaddr*)&addr2,&addrlen2);
if(User_fd == -1){
perror("accept");
exit(1);
}
if ((pid = fork())==0) {
close(listenfd);
while(1){
read(User_fd,buffer,364);
write(1,buffer,strlen(buffer)+1);
sscanf(buffer,"%s",check);
if(strcmp(check,"UPL")==0){
sscanf(buffer,"%s %s %s %ld %s",check,num_aluno,Fname,&Fsize,Fcontent);
write(1,Fcontent,strlen(Fcontent)+1);
}
}
freeaddrinfo(res);
close(User_fd);
exit(0);
}
}
}

Related

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.

Multiclient and server commandline argument issues

I have code for a server that can handle multiple clients. The client program can connect to the server and issue Unix commands such as ls, date, clear, etc. I have two problems that I cannot figure out. 1) When I initially type ls as an argument it will return some weird garbage, and then if I do ls again then it starts working properly. So only in the beginning, it will give me garbage. 2) When I type the argument 'ps -ael' into the terminal, it will work properly, but then after that I get a 'Failed' message, which is coming from the Client code, specifically at the while(1) loop where if (send(clientSocket, s, echolen, 0) != echolen), this is where the error is occurring. I was curious to know if someone could point to what the problem could be, I think it might be because I create a char array that's too big but I'm not sure.
Client:
#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>
#define PORT 4444
#define BUFFSIZE 2048
int main(int argc, char *argv[]){
int clientSocket, ret, portnum;
struct sockaddr_in serverAddr;
int received = 0;
unsigned int echolen;
char buffer[1024];
if(argc < 3){
fprintf(stderr,"usage %s <server-ip-addr> <server-port>\n", argv[0]);
exit(0);
}
portnum = atoi(argv[2]);
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
// memset(&buffer, '\0', sizeof(buffer));
// serverAddr.sin_family = AF_INET;
// serverAddr.sin_port = htons(PORT);
// serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// bzero((char *) &serverAddr, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
if(!inet_aton(argv[1], &serverAddr.sin_addr)){
fprintf(stderr, "Error invalid server IP address\n");
exit(1);
}
serverAddr.sin_port = htons(portnum);
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to server.\n");
char s[100];
while(1){
fgets(s, 100, stdin);
s[strlen(s)-1]='\0';
echolen = strlen(s);
/* send() from client; */
if (send(clientSocket, s, echolen, 0) != echolen)
{
printf("Failed");
}
if(strcmp(s,"exit") == 0) // check if exit is typed
exit(0);
fprintf(stdout, "Message from server: ");
while (received < echolen)
{
int bytes = 0;
/* recv() from server; */
if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1)
{
printf("Failed to get Information");
}
received += bytes;
buffer[bytes] = '\0';
fprintf(stdout, buffer);
}
int bytes = 0;
do {
buffer[bytes] = '\0';
printf("%s\n", buffer);
} while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
buffer[bytes] = '\0';
printf("%s\n", buffer);
printf("\n");
}
}
Server:
#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>
#define PORT 4444
#define BUFFSIZE 2048
#define MAX 2048
void setup(char inputBuffer[], char *args[], int *background){
const char s[4] = " \t\n";
char *token;
token = strtok(inputBuffer, s);
int i = 0;
while(token != NULL){
args[i] = token;
i++;
token = strtok(NULL, s);
}
args[i] = NULL;
}
void HandleClient(int sock){
char buffer[BUFFSIZE];
int received = -1;
char data[MAX];
memset(data, 0, MAX);
while(1){
data[0] = '\0';
if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
printf("Error");
}
buffer[received] = '\0';
strcat(data, buffer);
if(strcmp(data, "exit") == 0){
exit(0);
}
puts(data);
char *args[100];
setup(data, args, 0);
int pipefd[2], length;
if(pipe(pipefd)){
printf("failed to create pipe");
}
pid_t pid = fork();
char path[MAX];
if(pid==0)
{
close(pipefd[0]); // close the readonly side of the pipe
//close(1); // close the original stdout
dup2(pipefd[1],1); // duplicate pipfd[1] to stdout
dup2(pipefd[1], fileno(stderr));
//close(pipefd[0]); // close the readonly side of the pipe
close(pipefd[1]); // close the original write side of the pipe
printf("before execvp");
execvp(args[0],args); // finally execute the command
// exit(0);
}
else
if(pid>0)
{
close(pipefd[1]);
memset(path,'\0',MAX);
while(length=read(pipefd[0],path,MAX-1)){
//printf("Data read so far %s\n", path);
if(send(sock,path,strlen(path),0) != strlen(path) ){
printf("Failed");
}
fflush(NULL);
//printf("Data sent so far %s\n", path);
memset(path,0,MAX);
}
close(pipefd[0]);
//exit(1); removed so server will not terminate
}
else
{
printf("Error !\n");
exit(0);//
}
}
}
int main(){
int sockfd, ret;
struct sockaddr_in serverAddr;
int newSocket;
struct sockaddr_in newAddr;
socklen_t addr_size;
char buffer[1024];
pid_t childpid;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding");
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));
//worker
if((childpid = fork()) == 0){
close(sockfd);
while(1){
recv(newSocket, buffer, 1024, 0);
if(strcmp(buffer, ":exit") == 0){
printf("Disconnected from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
printf("Client: %s\n", buffer);
send(newSocket, buffer, strlen(buffer), 0);
bzero(buffer, sizeof(buffer));
}
HandleClient(newSocket);
}
}
}
close(newSocket);
return 0;
}

stop and wait in c, infinite timeouts

I'm having difficulties with this project. Everything's working except for binary files, probably because they're pretty big and would expect timeouts. The packetErrorSends are similar to send but they randomly drop packets. I only put them in the client side to isolate my problem. The algorithm I'm going for is send a piece of the file, if it receives it, send an 's' and continue reading and send the send piece. If it times out, send an 'e' and then hop in the loop, resend the current piece and recv the next status update. "While" checks the status, decides whether to move on or resend that piece. The problem is when is times out, server gets stuck in that loop resending the last chunk of data and client keeps timing out and sending back 'e's (the purpose of the print statements) Any clue what's happening?
client:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "packetErrorSend.h"
#include <sys/time.h>
ssize_t recvx(int sockfd, void *buf, size_t len) {
int var = recv(sockfd, buf, len, 0);
if(var != -1)
{
return var;
} else {
printf("%s \n","Did not receive.");
exit(1);
}
}
int main(int argc, char *argv[])
{
char buf[MAX_PACKET_DATA_SIZE];
struct addrinfo hints;
struct addrinfo *rp, *result;
int bytes_received = 1;
int s;
char *server;
char *port;
char *file;
int fd = -1; //file descriptor
int bytes_written = 1;
fd_set readfds;
struct timeval tv;
int rv = 0;
int status;
char sendStatus[1];
if (argc==4)
{
server = argv[1];
port = argv[2];
file = argv[3];
}
else
{
fprintf(stderr, "invalid # of arguments\n");
exit(1);
}
/* Translate host name into peer's IP address */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
if ((s = getaddrinfo(server, port, &hints, &result)) != 0 )
{
fprintf(stderr, "%s: getaddrinfo: %s\n", argv[0], gai_strerror(s));
exit(1);
}
/* Iterate through the address list and try to connect */
for (rp = result; rp != NULL; rp = rp->ai_next)
{
if ((s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1 )
{
continue;
}
if (connect(s, rp->ai_addr, rp->ai_addrlen) != -1)
{
break;
}
close(s);
}
if (rp == NULL)
{
perror("stream-talk-client: connect");
exit(1);
}
freeaddrinfo(result);
FD_ZERO(&readfds);
FD_SET(s, &readfds);
packetErrorSend(s, file, strlen(file)+1, 0);
tv.tv_sec = 2;
rv = select(s+1, &readfds, NULL, NULL, &tv);
if (rv == -1) {
perror("select"); // error occurred in select()
} else if (rv == 0) {
printf("Timeout occurred on filename! No data after 2 seconds.\n");
close(s);
exit(0);
} else {
status = recvx(s,buf,1);
}
if(status == 0 || buf[0] == 'e')
{
fprintf(stderr, "Server Error: unable to access file %s \n", file);
close(s);
exit(0);
}
if(buf[0] == 's')
{
fd =open(file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if(fd == -1)
{
fprintf(stderr,"%s \n","Client Error: Open failed");
close(s);
exit(0);
}
FD_ZERO(&readfds);
FD_SET(s, &readfds);
bytes_received = MAX_PACKET_DATA_SIZE;
// while(bytes_received >= MAX_PACKET_DATA_SIZE)
while(bytes_received > 0)
{
tv.tv_sec = 3;
rv = select(s+1, &readfds, NULL, NULL, &tv);
if (rv == -1) {
perror("select");
} else if (rv == 0) {
printf("bytes_received in timeout %d \n", bytes_received );
printf("Timeout occurred! No data after 3 seconds.\n");
sendStatus[0] = 'e';
send(s,sendStatus,1,0);
} else {
bytes_received = recvx(s, buf, MAX_PACKET_DATA_SIZE);
printf("%d\n", bytes_received);
sendStatus[0]='s';
packetErrorSend(s,sendStatus,1,0);
}
bytes_written = write(fd,buf,bytes_received);
if(bytes_written == -1)
{
fprintf(stderr,"%s \n", "Client Error: Write error");
break;
}
}
if(bytes_received == -1)
{
fprintf(stderr,"%s \n", "Client Error: Error receiving file");
exit(0);
}
if(close(fd) != 0)
{
printf("%s \n", "Client Error: File did not close successfully");
exit(0);
}
close(s);
}
return 0;
}
server:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "packetErrorSend.h"
#include <sys/time.h>
#define SERVER_PORT "5432"
#define MAX_PENDING 5
int main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *rp, *result;
char file[MAX_PACKET_DATA_SIZE];
int s, new_s;
int bytes_transferred = 0;
int fd; //file descriptor
char status[1];
/* Build address data structure */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
/* Get local address info */
if ((s = getaddrinfo(NULL, argv[1], &hints, &result)) != 0 )
{
fprintf(stderr, "%s: getaddrinfo: %s\n", argv[0], gai_strerror(s));
exit(1);
}
/* Iterate through the address list and try to perform passive open */
for (rp = result; rp != NULL; rp = rp->ai_next)
{
if ((s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1 )
{
continue;
}
if (!bind(s, rp->ai_addr, rp->ai_addrlen))
{
break;
}
close(s);
}
if (rp == NULL)
{
perror("stream-talk-server: bind");
exit(1);
}
if (listen(s, MAX_PENDING) == -1)
{
perror("stream-talk-server: listen");
close(s);
exit(1);
}
freeaddrinfo(result);
/* Wait for connection, then receive and print text */
while(1)
{
for(int i = 0; i < sizeof(file); i++)
{
file[i] = '\0';
}
if ((new_s = accept(s, rp->ai_addr, &(rp->ai_addrlen))) < 0)
{
perror("stream-talk-server: accept");
close(s);
exit(0);
}
if ((bytes_transferred = recv(new_s,file,sizeof(file),0)) > 0)
{
fd = open(file,O_RDONLY);
if(fd < 0)
{
perror("open");
status[0] = 'e';
send(new_s,status,1,0);
close(new_s);
exit(0);
}
status[0] = 's';
send(new_s,status,1,0);
int datasent = 0;
bytes_transferred = 1;
while(bytes_transferred > 0)
{
status[0] = s;
bytes_transferred = read(fd,file,MAX_PACKET_DATA_SIZE);
printf("%d\n",bytes_transferred);
datasent = send(new_s,file,bytes_transferred,0);
if (datasent < 0)
{
perror("send");
break;
}
recv(new_s,status,1,0);
printf("before while: %c \n", status[0]);
while(status[0] == 'e')
{
recv(new_s,status,1,0);
send(new_s,file,bytes_transferred,0);
printf("in while: %c \n", status[0]);
}
}
if (bytes_transferred == 0)
{
break;
}
else if(bytes_transferred == -1)
{
perror("read");
close(new_s);
exit(0);
}
}
}
close(fd);
close(new_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)

How to force sending data with socket

I'm building a Client/Server distributed application via socket in C.
Here is my server:
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <netinet/tcp.h>
#define LEN 20
int main(void) {
int err, nread, status, optval=1;
int sd, ns;
char category[LEN];
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if((err = getaddrinfo(NULL, "50000", &hints, &res)) != 0) {
printf("%s", gai_strerror(err));
exit(-1);
}
if((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
printf("Error in Socket Server\n");
exit(-1);
}
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
if(bind(sd, res->ai_addr, res->ai_addrlen) != 0) {
printf("Error in bind\n");
exit(-1);
}
freeaddrinfo(res);
if(listen(sd, 5) != 0) {
printf("Error in listen\n");
exit(-1);
}
for(;;) {
if((ns = accept(sd, NULL, NULL)) < 0) {
printf("Error in accept\n");
exit(-10);
}
/* I tried with this: setsockopt(ns, IPPROTO_TCP, TCP_NODELAY, (char*)&optval, sizeof(int));
but it didn't work out */
while((nread = read(ns, category, LEN)) > 0){
if(category[nread-1]=='\n') {
category[nread-1]='\0';
}
if(fork()==0) {
close(1);
dup(ns);
close(ns);
execlp("grep", "grep", category, "conto_corrente.txt", (char *)0);
perror("Error in fork\n");
exit(-100);
}
wait(&status);
}
close(ns);
}
}
And here is my client:
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
int err, nread;
int sd;
char category[20];
char buff[1024];
struct addrinfo hints, *res, *ptr;
if(argc!=3) {
printf("Error in number of parameters\n");
exit(-1);
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if((err = getaddrinfo(argv[1], argv[2], &hints, &res)) != 0) {
printf("%s\n", gai_strerror(err));
exit(-1);
}
for(ptr = res; ptr != NULL; ptr=ptr->ai_next) {
if((sd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) < 0) {continue;}
if((connect(sd, ptr->ai_addr, ptr->ai_addrlen)) == 0) {
break;
}
}
if(ptr==NULL) {
printf("Error in connection\n");
exit(-1);
}
freeaddrinfo(res);
printf("Category: ");
scanf("%s", category);
while(strcmp(category, "fine") != 0) {
write(sd, category, strlen(category)+1);
while((nread = read(sd, buff, 1024)) > 0) {
printf("%s", buff);
}
printf("Category: ");
scanf("%s", category);
}
close(sd);
return 0;
}
The program should take an input from the user (a string) and send it to the server which have to scan the file and select all the lines that contain that string.
I think there is a problem in the buffering because when the user enter a string then the client stops it looks like it is waiting for something, in fact if I kill the server then the client shows what it read. How is it?

Resources