[Mac OS X, Xcode 6.6.1]
I'm communicating between two separate processes using FIFOs (named pipes). I've greatly simplified the code for this forum, so that the "command" is a simple string that the server changes to upper case before sending it back.
Problems: When the client sends a short string like "abcdefg" the server sees a garbage character (upside-down "?") in place of the last char, and for long strings the whole string turns into garbage.
I've tried adding 1 to the char count in "write" and using an array of chars in place of the strings in "write". Neither helped. Any ideas?
The output for two cases, the only difference being the length of the string sent by the client ("?" inverted for visibility):
<client>
Trying to connect to server.
Sending 'abcdefg' to server.
Connection succeeded.
The reply was: ABCDEF?
Program ended with exit code: 0
<server>
Making fifos for send & rcv
Opening communications w/ client.
The input_string is:
abcdef?
The output_string is:
ABCDEF?
-----------------------
<client>
Trying to connect to server.
Sending 'abcdefghijklmnopqrstuvwxyz' to server.
Connection succeeded.
The reply was: ??????????????????????????
caseclient(43047,0x7fff72b37310) malloc: *** error for object 0x100104360: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
(lldb)
<server>
Making fifos for send & rcv
Opening communications w/ client.
The input_string is:
??????????????????????????
The output_string is:
??????????????????????????
Here is the server:
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
|
#include <string>
#include <iostream>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <algorithm>
#define FIFO_FROM_SERVER "/tmp/fifo_to_client"
#define FIFO_TO_SERVER "/tmp/fifo_from_client"
using namespace std;
struct raise_case {
int operator() ( int ch )
{
return std::toupper ( ch );
}
};
int main( int argc, const char * argv[] )
{
//- server -
// Get string from client and change to UPPER CASE; then send it back
int res, out_pipe, in_pipe;
std::string input_string, output_string;
std::cout << "Making fifos for send & rcv" << "\n";
// - server- make the FIFOs if not done already
if (access(FIFO_FROM_SERVER, F_OK) == -1) {
res = mkfifo(FIFO_FROM_SERVER, 0666);
if (res != 0) {
fprintf(stderr, "Could not create fifo %s\n",
FIFO_FROM_SERVER);
exit(1);
}
if (access(FIFO_TO_SERVER, F_OK) == -1) {
res = mkfifo(FIFO_TO_SERVER, 0666);
if (res != 0) {
fprintf(stderr, "Could not create fifo %s\n",
FIFO_TO_SERVER);
exit(1);
}
}
}
printf("Opening communications w/ client.\n");
if( (out_pipe = open(FIFO_FROM_SERVER, O_WRONLY )) < 1 ) {
perror("Error: open( ): ");
return 1;
}
do
{
// Wait for a request from the client.
const int MAX_READ_CHARS = 800;
if( (in_pipe = open(FIFO_TO_SERVER, O_RDONLY )) < 1 ) {
perror("Error: open( ): ");
return 1;
}
if( read( in_pipe, &input_string, MAX_READ_CHARS ) < 0 ) {
perror("Error: read( ): ");
return 1;
}
// Got a request from client.
std::cout << "The input_string is: \n" << input_string << "\n";
output_string = input_string;
// Capitalize all the letters and send back to client
std::transform(output_string.begin(), output_string.end(), output_string.begin(), raise_case());
std::cout << "The output_string is: \n" << output_string << "\n";
if( write( out_pipe, &output_string, output_string.length() ) < 0 ) {
perror("Error: write( ): ");
return 1;
}
close( in_pipe );
}
while (true);
return 0;
}
|
Here's the client:
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
|
//
// main.cpp
// testclient
//
#include <unistd.h>
#include <iostream>
#include <fcntl.h>
#include <chrono>
#define FIFO_FROM_SERVER "/tmp/fifo_to_client"
#define FIFO_TO_SERVER "/tmp/fifo_from_client"
int main( int argc, const char* argv[] ) {
int in_pipe, out_pipe, reply_size = 500;
std::string command, reply;
if (argc == 2) {
command = argv[1];
}
else {
command = "test";
}
printf("Trying to connect to server.\n");
if( (in_pipe = open(FIFO_FROM_SERVER, O_RDONLY, 0 )) == -1 ) {
perror("Error: open( ): ");
return 1;
}
if( (out_pipe = open(FIFO_TO_SERVER, O_WRONLY, 0 )) == -1 ) {
perror("Error: open( ): ");
return 1;
}
std::cout << "Sending '" << command << "' to server." << std::endl;
// Send a command to server
if( write( out_pipe, &command, command.length() ) < 0 ) {
perror("Error: write( ): ");
return 1;
}
close( out_pipe );
// Wait for reply
errno = 0;
long chars_read = read( in_pipe, &reply, reply_size );
if( chars_read < 0 ) {
perror("Error: read( ): ");
return 1;
}
printf("Connection succeeded.\n");
std::cout << "The reply was: " << reply << std::endl;
close( in_pipe );
return 0;
}
|
Thanks for any help- Scott