Problem with server in client-server program

I am doing a server-client program in C++ and am having trouble figuring out how to do a couple of things. I already have the server and client up and running and they are able to exchange simple messages. What I need to do is have the client send the name of a file to the server and have the server run a function on that file name and return the output to the client.

I am lost on
1) How to pass the file name when the server receives it (in main) to the appropriate function outside of main.
2) How to return the output from the function (about 250 lines) to the client

Any help/tips on how to do this would be greatly appreciated.
Last edited on
http://www.cis.gvsu.edu/~wolffe/courses/cs656/projects/tutorial_CSockets.html

line 88: write() takes a char* as the 2nd parameter
all you have to do is convert the filename accordingly

then read() it on the client side into another char* buffer


You're missing an important loop for processing the server messages.
I've only done it in a windows environment but it basically starts like this:

//ReceiveProtocolMessage(lParam)
{
switch(lParam)
{
case FD_READ:
case FD_WRITE:
case FD_ACCEPT: //Connection request to server
case FD_CONNECT:
case FD_CLOSE:
}
}

I'm not sure if it's best, but the way I would do it is open a txt or data file and output the results and filename there. Then, once a certain quota size is reached, open/read that file and load the char* buffer to send to the client.

Then the client side would be similar. Process the data file once it reaches a certain quota that you decide on.

A couple things to keep in mind.
1-There is a limit to how much the buffer can hold.
2-There could be an error or an incomplete data packet that is sent over the network due to various reasons.

So, good practice is to always put a unique terminating sequence of chars that is always tested for on the other side of the server. That way you can be sure that the entire msg was sent and either resend or do something else if it was incomplete.

like: "myfilename.exe=-+="
Last edited on
I already have the server and client up and running and they are able to exchange simple messages.
You server reads one message, sends a reply, then terminates.

Normally a server will have a loop that does that, so it doesn't terminate after one session.

The loop starts at line 73, the call to accept(), something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
do
{
	socklen_t clien = sizeof(struct sockaddr);
	int newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
	if (newsockfd < 0)
		error("ERROR on accept");

	char buffer[256];
	bzero(buffer, sizeof(buffer));
	int n = read(newsockfd, buffer, sizeof(buffer) - 1);
	if (n < 0)
		error("ERROR reading from socket");
	printf("Processing numbers for file: %s",buffer);

	char reply[256];
	// process buffer and build reply

	n = write(newsockfd, reply, strlen(reply) + 1);
	if (n < 0)
		error("ERROR writing to socket"); 
	close(newsockfd);
}


The client and server have to agree what to send, how to terminate the message, and what to do with the message (the protocol) as TCP is only concerned with sending sequences of bytes.

What I need to do is have the client send the name of a file to the server and have the server run a function on that file name and return the output to the client.
Let's imagine your protocol gets the length of a specified filename.

You decide that the client sends FILE <filename> LENGTH in a zero terminated string. The process code looks something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
std::istringstream s(buffer);
std::string action;
s >> action;
if (action == "FILE")
{
	std::string filename, verb;
	s >> filename >> verb;
	if (verb == "LENGTH")
	{
		struct stat info;
		if (stat(filename.c_str(), &info) != -1)
			snprintf(reply, sizeof(reply), "%ld", info.st_size);
		else
			snprintf(reply, sizeof(reply), "error %d accessing file %s", errno, filename.c_str());
	}
	else
		snprintf(reply, sizeof(reply), "unrecognised verb on file: %s", filename.c_str());
}
else
	snprintf(reply, sizeof(reply), "unrecognised action %s", action.c_str());


I hope this answers all the questions.
Last edited on
Soranz and kbw,

Thank you both for your help so far. I was able to finally get the server to pass the filename correctly. Problem was on the client side.I was using fgets and apparently that added the newline character to the end of the string and so when it was passed to the server it was passing it incorrectly.

I've modified my code a bit so as to remove the ProcessNumbers function and have that be done in main.

I am still at a loss on how I can send the results that I need to send to the client into the buffer so that the server can send them. I've looked at few examples and read about sockets on different sites but I just can't figure it out.

How would I got about sending the cout lines at 64 and 68 into the reply buffer so that they can be sent to the client. As of now, what the client gets back after sending the filename is a few characters of gibberish( like íéC+).
Last edited on
I am still at a loss on how I can send the results that I need to send to the client into the buffer so that the server can send them.
Read my post again and look at the code.

Ask questions about parts you don't understand; I've posted a full server solution that returns the size of the named file.
Topic archived. No new replies allowed.