Hi all,
I'm writing a socket program which sends a structure from one machine to another. When I run my client first time it runs well, however after the first time I couldn't receive all the data inside the structure (it is like, half of the array is received and the other half is not set). I think it is related with the socket's receive buffer size or the amount of data that I can send through the network (I'm not sure though, but sender side returns the correct byte size as sent data). Do you have any idea what I'm missing? Is there any information that I need to consider while sending my data such as maximum size or something else?
Below is my code:
config.h
#define TOLDATA 512*2 //Maximum data elements that are going to be sent through network
/* States of the protocol.
* At the moment they are only:
*
* NOOP: No operation
* TRANSMIT : During data transmission
* COMPLETE : Data transmission complete
*/
#define TRANSMIT 0x01
#define COMPLETE 0x02
/* This is the basic structure that is used for
* transferring data from one place to other
* @param state Current machine's state
* @param dataSize exact number of elements in data array
* @param data data to be transmitted
*
*/
typedef struct Tol_Data{
char state;
int dataSize;
double data[TOLDATA];
} TolData;
#define RCVBUFSIZE sizeof(TolData) //Maximum bytes that can be received
client.cpp
#include "PracticalSocket.h" // For Socket and SocketException
#include <iostream> // For cerr and cout
#include <cstdlib> // For atoi()
#include "config.h"
using namespace std;
TolData* getDumbData(){
TolData* data = new TolData();
for(int i=0;i<TOLDATA;i++)
data->data=TOLDATA-i;
data->dataSize=TOLDATA;
data->state=TRANSMIT;
return data;
}
int main(int argc, char *argv[]) {
if ((argc < 2) || (argc > 4)) { // Test for correct number of arguments
cerr << "Usage: " << argv[0]
<< " <Server> " << endl;
exit(1);
}
string servAddress = argv[1]; // First arg: server address
TolData* data = getDumbData();
int dataSize = sizeof(*data);// Determine input length
unsigned short echoServPort = 20000;
try {
// Establish connection with the server
TCPSocket sock(servAddress, echoServPort);
//Send data
int snt=sock.send(data, dataSize);
cout << "data has been sent: " << snt << endl;
} catch(SocketException &e) {
cerr << e.what() << endl;
exit(1);
}
return 0;
}
server.cpp
#include "PracticalSocket.h" // For Socket, ServerSocket, and SocketException
#include <iostream> // For cerr and cout
#include <cstdlib> // For atoi()
#include <vector>
#include "config.h"
using namespace std;
vector<double> myData;
void HandleTCPClient(TCPSocket *sock, TolData* echoBuffer); // TCP client handling function
int main(int argc, char *argv[]) {
if (argc != 2) { // Test for correct number of arguments
cerr << "Usage: " << argv[0] << " <Server Port>" << endl;
exit(1);
}
unsigned short echoServPort = atoi(argv[1]); // First arg: local port
//Buffer for receive
TolData* echoBuffer=new TolData();
try {
TCPServerSocket servSock(echoServPort); // Server Socket object
for (;;) { // Run forever
HandleTCPClient(servSock.accept(),echoBuffer); // Wait for a client to connect
}
} catch (SocketException &e) {
cerr << e.what() << endl;
exit(1);
}
// NOT REACHED
return 0;
}
//Assuming that this data is double
//later i need to figure out how to extend
//this type definition to template T
void handleData(double *recvData, unsigned int size){
for(int i=0;i<size;i++){
cout << "Data is about to be added: " << *recvData<< endl;
myData.push_back(*(recvData++));
}
}
// TCP client handling function
void HandleTCPClient(TCPSocket *sock, TolData* echoBuffer) {
cout << "Handling client ";
try {
cout << sock->getForeignAddress() << ":";
} catch (SocketException e) {
cerr << "Unable to get foreign address" << endl;
}
try {
cout << sock->getForeignPort();
} catch (SocketException e) {
cerr << "Unable to get foreign port" << endl;
}
cout << endl;
int recvMsgSize;
while ((recvMsgSize = sock->recv(echoBuffer, RCVBUFSIZE)) > 0) {
cout << "data is received size:" <<recvMsgSize<< endl;
TolData *received = echoBuffer;
if(received->state && TRANSMIT)
//Send data and size information to the handle function
handleData(received->data,received->dataSize);
//At the moment COMPLETE state is not being used
if(received->state && COMPLETE)
break;
}
cout << "All data have been received!" << endl;
delete sock;
}
PracticalSocket is a small lib. that I'm using for connection, sending data and receiving it.
After I run server, I execute client several times from terminal and I'm getting the problem after first execution (or sometimes at my first execution). If I change the value in TOLDATA in config.h like <=512, it is working.
Any suggestions?
Thanks in advance.