Basic TCP server to process GET

I am writing a TCP server that will allow clients to connect and run the GET command.

1. Server is run and has a base directory already specified
2. Client connects
3. Client sends GET filename or GET directory. This must be processed by the server in a child process using fork. If a filename is specified it displays the contents otherwise it lists off files.

I have the server running and it is able to read user input but it will not run a single command. I'm thinking I may need a separate section of code to process directories.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <cstring>
#include <netinet/udp.h>
#include <cstdlib>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <ctype.h>

using namespace std;

int main(int argc, char * argv[])
{
	int sock;
	unsigned int serverlen;
	unsigned int clientlen;
	char buffer[256]; 
	int	received = 0; 
	char command[100];
	int count=0;
	char *comnd1[] = { "/bin/ls", "-l", NULL, NULL, NULL, NULL };
	struct sockaddr_in echoserver; 
	struct sockaddr_in echoclient; 
	// Create the TCP socket
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
	{ 
		perror("Failed to create socket");
		exit(EXIT_FAILURE);
	}
	
	// Construct the server sockaddr_in structure 
	memset(&echoserver, 0, sizeof(echoserver)); 
	echoserver.sin_family = AF_INET; 
	echoserver.sin_addr.s_addr = INADDR_ANY; 
	echoserver.sin_port = htons(atoi(argv[1]));	
	
	// Bind the socket
	serverlen = sizeof(echoserver);
	if (bind(sock, (struct sockaddr *) &echoserver, serverlen) < 0) 
	{ 
		perror("Failed to bind server socket");
		exit(EXIT_FAILURE);
	}
	
	// listen: make socket passive and set length of queue 
	if (listen(sock, 64) < 0) 
	{
		perror("listen failed");
		exit(EXIT_FAILURE);
	}
	
	// Run until cancelled
	while (int newSock=accept(sock, (struct sockaddr *) &echoclient, &clientlen)) 
	{ 
		if ((received = read(newSock, buffer, 256)) < 0)
		{
			perror("Failed to receive message");
			exit(EXIT_FAILURE);
		}
		
		if (fork()) 
		{	// parent process
		close(sock);
		} 
		else
		{	
			// duplicate socket descriptor into standard output
			if (dup2(sock, 1) < 0) 
			{
				perror("socket dup2");
				exit(EXIT_FAILURE);
			}	
			// prepare argv array of strings
			char *argv[] = { (char*)0, (char*)0, (char*)0, (char*)0, (char*)0,(char*)0, (char*)0 };
			// parse command into words
			for (char *p = strtok(buffer, " "); p; p = strtok(NULL, " "))
			{
				argv[count++] = p;
			}
			write(newSock, argv[1], received);
			// run command and its arguments via execvp
			if (execvp(argv[0], argv) < 0) 
			{
				perror("exec in child after fork");
				exit(EXIT_FAILURE);
			}
		}
	}
}
Last edited on
Topic archived. No new replies allowed.