Reputation: 11961
I'm using socket as a bridge between a C program and a Java program. C side is the server socket and receives the data from the Java side to process the data and send back the result. Java side is the client socket and sends the data to C side for processing and then receives the result from C side.
C side code (server):
const int SOCKET_BUF_IN_LEN = 160024; //socket_buf_in length
const int SOCKET_BUF_OUT_LEN = 5000; //socket_buf_out length
unsigned char socket_buf_in[SOCKET_BUF_IN_LEN];
unsigned char socket_buf_out[SOCKET_BUF_OUT_LEN];
struct AlgSocketIn alg_socket_in;
struct AlgSocketOut alg_socket_out;
//... some socket connection setup code
setsockopt(new_socket_fd, SOL_SOCKET, SO_RCVBUF, &SOCKET_BUF_IN_LEN, sizeof(SOCKET_BUF_IN_LEN));
bytes_recv = recv(new_socket_fd, socket_buf_in, SOCKET_BUF_IN_LEN, 0);
run_alg(); //process the data
bytes_send = send(new_socket_fd, socket_buf_out, SOCKET_BUF_OUT_LEN, 0);
The socket send buffer socket_buf_in
has 160024 bytes as indicated above. I set the socket buffer to be this size by using setsockopt()
.
Java side code (client):
public AlgOutData sendRecvData(AlgInData inData, int portNum) {
AlgOutData outData = new AlgOutData();
Socket sock = new Socket("localhost", portNum);
int sentBytes, recvBytes;
sock.setSendBufferSize(160024);
sentBytes = serializeData(inData, sock); //send data to server
recvBytes = deserializeData(outData, sock); //receive result from server
sock.close();
return outData;
}
private int serializeData(AlgInData inData, Socket socket) throws IOException {
int totalNumSamples = 160024;
DataOutputStream os = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), 160024));
for(int i=0; i<totalNumSamples; i++) {
os.writeByte(inData.getSamples()[i]);
}
os.flush();
int numBytes = os.size();
return numBytes;
}
But when I started both the C program and Java program and upon finishing sending bytes from Java side to C side, I found that C side only received 65536 bytes from TCP socket stream. I debugged it and found this by looking at this line in C code:
bytes_recv = recv(new_socket_fd, socket_buf_in, SOCKET_BUF_IN_LEN, 0);
Upon finishing this call, bytes_recv
is 65536 bytes, not 160024 bytes which is the length of the socket_buf_in
.
However on Java side, I found that the data sent is indeed 160024 bytes. In serializeData()
, the line shows
//....
os.flush();
int numBytes = os.size();
numBytes
is 160024 after the call to os.flush()
.
So why do I only get 65536 bytes of data on C side while Java side sends all 160024 bytes data? Do I use the correct socket send/receive functions correctly on C side?
I also tried using the following code on C side to repeatedly receive byte stream until all 160024 bytes are received:
num_bytes = 0;
while (num_bytes < SOCKET_BUF_IN_LEN) {
bytes_recv = recv(new_socket_fd, socket_buf_in, SOCKET_BUF_IN_LEN, 0);
if (bytes_recv < 0)
handle_error("Error on socket recv.\n");
num_bytes += bytes_recv;
}
But this time, even though num_bytes
is 160024, the socket buffer socket_buf_in[160024]
has all zero values, which is wrong.
On the other hand, when I debugged the Java side code, I found that even though I set the output stream object os
to have 160024 buffer size, it only writes bytes correctly up to 20024 bytes, not 160024 bytes.
What is wrong in either C side or Java side code for socket communication of 160024 bytes?
Upvotes: 0
Views: 769
Reputation: 1841
You final loop looks almost correct, however you'll need to move the pointer passed into recv as you read data into the array. Otherwise each call is overwriting the beginning of the array. Something like
bytes_recv = recv(new_socket_fd, socket_buf_in+num_bytes, SOCKET_BUF_IN_LEN, 0);
Upvotes: 1