I am facing another TCP Socket issue. I've read through a huge bunch of questions an answers to similar issues, but my problem is somehow different.
I have a Java Client and C++ Server. Everything goes as expected until I'm using different machines (equal to other issues so far) The messages from the client seem to getting stuck in den TCP Buffer. When I finally close the socket, everything is sent to the server. But these single messages are controlmessages so I need them to be send immediatly. As far as I read this is expected behavior, but how do I send reliable control messages.
Is there a way to force the messages to be sent. (I can leave the socket open for a couple of minutes with nothing is sent.)
Is there something wrong? (see the following code)
Do I have to close the socket each time to perform a REAL flush?
Should I use UDP instead, with an additional amount of protocol work?
Javacode:
mSocketSend = new Socket();
mSocketSend.connect(new InetSocketAddress(mServerIp, mSocketPortSend), mTimeOut);
PrintWriter pw = new PrintWriter(mSocketSend.getOutputStream(), true);
pw.println(data);
C++ Code:
opening socket...(i leave that)
char* buffer = new char[1024];
int rc = recv(mConnectedSocket, buf, 1024, 0);
If you want more of it. Write it. I left almost everything out. ^^ I dont think its relevant. The Communication wents great usually.. No errors at all. So its just this TCPBuffer thingi.
I know there should be some delimiter or message length stuff. But in fact: A message length, which is not sent, does not help. ^^
Thanks for your help.
EDIT #01 The whole bunch of code:
mSocket->createSocketServer(22);
char* buffer = new char[1024];
while(true){
int numberBytes = mSocket->receiveChars(buffer, 1024);
if (numberBytes > 0){
uninterestingHandlingFunction(buffer);
}else{
mSocket->createSocketServer(22);
}
}
bool Socket::createSocketServer(u_short port)
{
if (mConnectedSocket != INVALID_SOCKET)
{
closesocket(mConnectedSocket);
}
if (s == INVALID_SOCKET)
{
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,0), &wsa) != 0)
return 0;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET)
return 0;
SOCKADDR_IN addr;
memset(&addr, 0, sizeof(SOCKADDR_IN));
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=ADDR_ANY;
if (bind(s, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
s = INVALID_SOCKET;
} else if (listen(s, 10) == SOCKET_ERROR)
{
s = INVALID_SOCKET;
}
if (s == INVALID_SOCKET)
{
closesocket(s);
return 0;
}
}
mConnectedSocket = accept(s, NULL, NULL);
if (mConnectedSocket == INVALID_SOCKET)
{
closesocket(s);
return 0;
}
return 1;
}
int Socket::receiveChars(char* buf, unsigned maxSize)
{
if (mConnectedSocket == INVALID_SOCKET)
return -1;
int rc = recv(mConnectedSocket, buf, maxSize, 0);
if (rc == SOCKET_ERROR)
{
std::cout << "Socket: error " << WSAGetLastError() << std::endl;
}
return rc;
}
You wanted it....
EDIT #2 Give it one more try
There are few more things I tried out. At first: This problem does not occure on a device connected over real network everytime. -> Full Reboot Client&Server -> Problem does not occure -> Full Reboot Client&Server -> Problem occures
Sadly, I don't know what to take from this habit.
Another thing I stumbled over is the bind and listen socket (in Code SOCKET s). This socket listens for connections and if the working thread needs a new connection (on startup or if the previous closes) the socket s gives the next queued connection to mConnectedSocket for recv, other connections are backlogged while one is processed. From the Java view: a Socket is connected (Device A). next socket (Device B) tries to connect. -> Connection success (its properly controlled in code if this is happens indeed) -> followed by sending data in natural matter. (The socket is still in the backlog on c++ side)
Well, this is hard to transform to the habit I experienced. I'll try to express my thoughts. Javaside: PrintWriter is created. Feeded with data and is flushed. Because the connection is not fully established (No additional connectedSocket on C++ side). The flush doesn't work. And onClose the socket finally flushes its content.
Please tell me to shut up, if you think so. I dont really know what the "Connection is backlogged" ACTUALLY mean in implementation" ^^
I know, I should open a new thread for each connection, but I can't at the moment. So stick with this server code.
pw.flush()? - Mattias Isegran Bergander