(C++/UNIX) I have the 2 files for a tcp server. The server program isnt working properly though. It needs to send inform
Posted: Sun May 15, 2022 10:19 am
(C++/UNIX)
I have the 2 files for a tcp server.
The server program isnt working properly though. It
needs to send information back to the client. here is an example
run (CLIENT IS DONE PROPERLY):
The instructions:
Implement a C++ program that in a loop listens on a port for
incoming TCP requests from clients. For each accepted incoming
request it forks a child to read and process the request. The
parent process continues to listen and accept incoming TCP requests
in an endless loop.
The program accepts 2 command line parameters:
For example:
% ./z1234567 9001 www
The requests received by the program are of the form:
GET pathname
where the pathname refers to a file or directory to be sent back
to the client. The file/directory will be found in the directory
specified on the command line. The following rules apply to the
pathname:
If the pathname refers to a file, then the content of the file
is returned to the client.
If the pathname refers to a directory, then:
Error Checking
If the command line arguments are incomplete, or if the path to
the root directory is invalid, print an error message and exit. If
any of the system calls fail, the program should use "perror" to
report and exit. If the pathname in the GET request is invalid or a
file/directory cannot be accessed, then an appropriate error
message should be constructed and sent back to the
client.
SERVER:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <cstdio>
#include <dirent.h>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
void client_request(int connsock)
{
int received;
char path[1024],buffer[1024];
if((received=read(connsock,path,sizeof(path)))<0)
{
perror("received");
exit(1);
}
cout<<"client requested:
"<<path<<endl;
if(strcmp(path,".")!=-1)
{
cout<<"Here are the contents of
the file:\n";
if(open(path,O_RDONLY)<0)
{
cerr<<"No such file
exist\n";
exit(1);
}
exit(EXIT_SUCCESS);
}
else
{
DIR *dirp=opendir(path);
if (dirp==0)
{
strcpy(buffer,path);
strcat(buffer, ": couldn't
open directory\n");
if(write(connsock,buffer,strlen(buffer))<0)
{
perror("write");
exit(1);
}
exit(EXIT_SUCCESS);
}
struct dirent *dirEntry;
while ((dirEntry = readdir(dirp)) !=
NULL)
{
strcpy(buffer,dirEntry->d_name);
strcat(buffer,"\n");
if(write(connsock,buffer,strlen(buffer))<0)
{
perror("write");
exit(1);
}
cout<<"Sent:
"<<buffer;
}
closedir(dirp);
close(connsock);
exit(EXIT_SUCCESS);
}
}
int main(int argc,char *argv[])
{
if(argc!=3)
{
perror("USAGE: path name and port
#");
exit(1);
}
int sock;
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("Failed to create socket");
exit(1);
}
struct sockaddr_in server_address;
struct sockaddr_in client_address;
unsigned int addrlen=sizeof(client_address);
memset(&server_address,0,sizeof(server_address));
server_address.sin_family=AF_INET;
server_address.sin_port=htons(atoi(argv[1]));
server_address.sin_addr.s_addr=INADDR_ANY;
if(bind(sock,(struct
sockaddr*)&server_address,sizeof(server_address))<0)
{
perror("Failed to bind server");
exit(1);
}
if(listen(sock,64)<0)
{
perror("listen failed");
exit(1);
}
cout<<"Server listening in on port:
"<<argv[1]<<endl;
while(true)
{
int connsock=accept(sock,(struct
sockaddr*)&client_address,&addrlen);
if(connsock<0)
{
perror("accept");
exit(1);
}
if(fork()){close(connsock);}
else
{
client_request(connsock);
}
}
}
CLIENT:
/*
* TCPClient.cxx
*
* TCP client
*
* sends message to TCP server
* waits for message received from
server
*
* command line arguments:
* argv[1] FQDN of
server
* argv[2] port number
to send to
* argv[3] request to
send
*
*/
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
if (argc != 4) {
cerr << "USAGE:
TCPClient server_name port request\n";
exit(EXIT_FAILURE);
}
// lookup FQDN
struct addrinfo *res, hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
int error = getaddrinfo(argv[1], argv[2],
&hints, &res);
if (error) {
cerr << argv[1]
<< ": " << gai_strerror(error) << endl;
exit(EXIT_FAILURE);
}
char buffer[1024];
int sent, received;
// Create the TCP socket
int sock = socket(AF_INET, SOCK_STREAM,
0);
if (sock < 0) {
perror("Failed to create
socket");
exit(EXIT_FAILURE);
}
// connect to server
if (connect(sock, res->ai_addr,
res->ai_addrlen) < 0) {
perror("connect");
exit(EXIT_FAILURE);
}
// Send the message string to the
server
sent = write(sock, argv[3],
strlen(argv[3])+1);
if (sent < 0) {
perror("write");
exit(EXIT_FAILURE);
}
// Receive the message back from the
server
do {
received = read(sock, buffer,
sizeof(buffer));
if (received < 0) {
perror("read");
exit(EXIT_FAILURE);
}
cout.write(buffer,
received);
} while (received > 0);
cout << endl;
close(sock);
}
I have the 2 files for a tcp server.
The server program isnt working properly though. It
needs to send information back to the client. here is an example
run (CLIENT IS DONE PROPERLY):
The instructions:
Implement a C++ program that in a loop listens on a port for
incoming TCP requests from clients. For each accepted incoming
request it forks a child to read and process the request. The
parent process continues to listen and accept incoming TCP requests
in an endless loop.
The program accepts 2 command line parameters:
For example:
% ./z1234567 9001 www
The requests received by the program are of the form:
GET pathname
where the pathname refers to a file or directory to be sent back
to the client. The file/directory will be found in the directory
specified on the command line. The following rules apply to the
pathname:
If the pathname refers to a file, then the content of the file
is returned to the client.
If the pathname refers to a directory, then:
Error Checking
If the command line arguments are incomplete, or if the path to
the root directory is invalid, print an error message and exit. If
any of the system calls fail, the program should use "perror" to
report and exit. If the pathname in the GET request is invalid or a
file/directory cannot be accessed, then an appropriate error
message should be constructed and sent back to the
client.
SERVER:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <cstdio>
#include <dirent.h>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
void client_request(int connsock)
{
int received;
char path[1024],buffer[1024];
if((received=read(connsock,path,sizeof(path)))<0)
{
perror("received");
exit(1);
}
cout<<"client requested:
"<<path<<endl;
if(strcmp(path,".")!=-1)
{
cout<<"Here are the contents of
the file:\n";
if(open(path,O_RDONLY)<0)
{
cerr<<"No such file
exist\n";
exit(1);
}
exit(EXIT_SUCCESS);
}
else
{
DIR *dirp=opendir(path);
if (dirp==0)
{
strcpy(buffer,path);
strcat(buffer, ": couldn't
open directory\n");
if(write(connsock,buffer,strlen(buffer))<0)
{
perror("write");
exit(1);
}
exit(EXIT_SUCCESS);
}
struct dirent *dirEntry;
while ((dirEntry = readdir(dirp)) !=
NULL)
{
strcpy(buffer,dirEntry->d_name);
strcat(buffer,"\n");
if(write(connsock,buffer,strlen(buffer))<0)
{
perror("write");
exit(1);
}
cout<<"Sent:
"<<buffer;
}
closedir(dirp);
close(connsock);
exit(EXIT_SUCCESS);
}
}
int main(int argc,char *argv[])
{
if(argc!=3)
{
perror("USAGE: path name and port
#");
exit(1);
}
int sock;
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("Failed to create socket");
exit(1);
}
struct sockaddr_in server_address;
struct sockaddr_in client_address;
unsigned int addrlen=sizeof(client_address);
memset(&server_address,0,sizeof(server_address));
server_address.sin_family=AF_INET;
server_address.sin_port=htons(atoi(argv[1]));
server_address.sin_addr.s_addr=INADDR_ANY;
if(bind(sock,(struct
sockaddr*)&server_address,sizeof(server_address))<0)
{
perror("Failed to bind server");
exit(1);
}
if(listen(sock,64)<0)
{
perror("listen failed");
exit(1);
}
cout<<"Server listening in on port:
"<<argv[1]<<endl;
while(true)
{
int connsock=accept(sock,(struct
sockaddr*)&client_address,&addrlen);
if(connsock<0)
{
perror("accept");
exit(1);
}
if(fork()){close(connsock);}
else
{
client_request(connsock);
}
}
}
CLIENT:
/*
* TCPClient.cxx
*
* TCP client
*
* sends message to TCP server
* waits for message received from
server
*
* command line arguments:
* argv[1] FQDN of
server
* argv[2] port number
to send to
* argv[3] request to
send
*
*/
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
if (argc != 4) {
cerr << "USAGE:
TCPClient server_name port request\n";
exit(EXIT_FAILURE);
}
// lookup FQDN
struct addrinfo *res, hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
int error = getaddrinfo(argv[1], argv[2],
&hints, &res);
if (error) {
cerr << argv[1]
<< ": " << gai_strerror(error) << endl;
exit(EXIT_FAILURE);
}
char buffer[1024];
int sent, received;
// Create the TCP socket
int sock = socket(AF_INET, SOCK_STREAM,
0);
if (sock < 0) {
perror("Failed to create
socket");
exit(EXIT_FAILURE);
}
// connect to server
if (connect(sock, res->ai_addr,
res->ai_addrlen) < 0) {
perror("connect");
exit(EXIT_FAILURE);
}
// Send the message string to the
server
sent = write(sock, argv[3],
strlen(argv[3])+1);
if (sent < 0) {
perror("write");
exit(EXIT_FAILURE);
}
// Receive the message back from the
server
do {
received = read(sock, buffer,
sizeof(buffer));
if (received < 0) {
perror("read");
exit(EXIT_FAILURE);
}
cout.write(buffer,
received);
} while (received > 0);
cout << endl;
close(sock);
}