Here's my code:
// Not all headers are relevant to the code snippet. #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <cstdlib> #include <cstring> #include <unistd.h> char *buffer; stringstream readStream; bool readData = true; while (readData) { cout << "Receiving chunk... "; // Read a bit at a time, eventually "end" string will be received. bzero(buffer, BUFFER_SIZE); int readResult = read(socketFileDescriptor, buffer, BUFFER_SIZE); if (readResult < 0) { THROW_VIMRID_EX("Could not read from socket."); } // Concatenate the received data to the existing data. readStream << buffer; // Continue reading while end is not found. readData = readStream.str().find("end;") == string::npos; cout << "Done (length: " << readStream.str().length() << ")" << endl; }
It's a little bit of C and C++ as you can tell. The BUFFER_SIZE is 256 - should I just increase the size? If so, what to? Does it matter?
I know that if "end" is not received for what ever reason, this will be an endless loop, which is bad - so if you could suggest a better way, please also do so.
The socket() function shall create an unbound socket in a communications domain, and return a file descriptor that can be used in later function calls that operate on sockets. The socket() function takes the following arguments: domain. Specifies the communications domain in which a socket is to be created.
Type C (electrical socket/electrical plug) The Type C plug (also called the Europlug) has two round pins. The pins are 4 to 4.8 mm wide with centers that are spaced 19 mm apart; the plug fits any socket that conforms to these dimensions.
It reads input from the user on the standard input stream, and then forwards that text to the echo server by writing the text to the socket. The server echoes the input back through the socket to the client. The client program reads and displays the data passed back to it from the server.
TCP sockets are used for communication between a server and a client process. The server's code runs first, which opens a port and listens for incoming connection requests from clients. Once a client connects to the same (server) port, the client or server may send a message.
Without knowing your full application it is hard to say what the best way to approach the problem is, but a common technique is to use a header which starts with a fixed length field, which denotes the length of the rest of your message.
Assume that your header consist only of a 4 byte integer which denotes the length of the rest of your message. Then simply do the following.
// This assumes buffer is at least x bytes long, // and that the socket is blocking. void ReadXBytes(int socket, unsigned int x, void* buffer) { int bytesRead = 0; int result; while (bytesRead < x) { result = read(socket, buffer + bytesRead, x - bytesRead); if (result < 1 ) { // Throw your error. } bytesRead += result; } }
Then later in the code
unsigned int length = 0; char* buffer = 0; // we assume that sizeof(length) will return 4 here. ReadXBytes(socketFileDescriptor, sizeof(length), (void*)(&length)); buffer = new char[length]; ReadXBytes(socketFileDescriptor, length, (void*)buffer); // Then process the data as needed. delete [] buffer;
This makes a few assumptions:
Since it is common to want to explicitly know the size of the integer you are sending across the network define them in a header file and use them explicitly such as:
// These typedefs will vary across different platforms // such as linux, win32, OS/X etc, but the idea // is that a Int8 is always 8 bits, and a UInt32 is always // 32 bits regardless of the platform you are on. // These vary from compiler to compiler, so you have to // look them up in the compiler documentation. typedef char Int8; typedef short int Int16; typedef int Int32; typedef unsigned char UInt8; typedef unsigned short int UInt16; typedef unsigned int UInt32;
This would change the above to:
UInt32 length = 0; char* buffer = 0; ReadXBytes(socketFileDescriptor, sizeof(length), (void*)(&length)); buffer = new char[length]; ReadXBytes(socketFileDescriptor, length, (void*)buffer); // process delete [] buffer;
I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With