I'm programming a Java server and a C++ client with the purpose of send Strings between them. But I am having so much problems with C++...
On my server, I create the server socket that listens on. After connection I expect a client message with:
entrada = new DataInputStream(socketCliente1.getInputStream());
mensajeRecibido=entrada.readUTF();
In my client I create the socket and connect as follows:
SOCKET ConnectSocket = INVALID_SOCKET;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
struct addrinfo *result = NULL, *ptr = NULL, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo("192.168.0.17", DEFAULT_PORT, &hints, &result);
ptr = result;
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
freeaddrinfo(result);
The problem comes here ... How do I send the String to the Java server?
And if I write in the Java server as:
output = new DataOutputStream (socketCliente1.getOutputStream ());
salida.writeUTF ("Hello");
How could receive with my C++ client?
If it's possible I would like not to touch the code in Java, because it has to work with Java clients too (which I have not had any problems to implement).
I don't have so much idea about C, so please, if it's possible tell me details like the libraries to use in the answer.
Related
After successfully connected to a tcp socket server, how can i sent the messages to that server?
i have created this client, and is working fine as long as is a two way communication with the server REPLYING FIRST.
final Flow<ByteString, ByteString, CompletionStage<Tcp.OutgoingConnection>> connection =
Tcp.get(system).outgoingConnection("127.0.0.1", 8888);
final Flow<ByteString, ByteString, NotUsed> repl = Flow.of(ByteString.class)
.map(ByteString::utf8String)
.map(
text -> {
System.out.println("Server: " + text);
return "next";
}
)
.map(ByteString::fromString);
CompletionStage<Tcp.OutgoingConnection> connectionCS = connection.join(repl).run(system);
after handshake, i need to send the credentials, AND I HAVE NO IDEA HOW.
in plain java it would be something like that:
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket)factory.createSocket(hostname, 8888);
socket.setReceiveBufferSize(1024 * 1000 * 2);
socket.startHandshake();
PrintWriter out = this.getPrintWriter(socket);
BufferedReader in = this.getBufferedReader(socket);
out.write(Authentication.getAsJson(loginApi.getAuthToken()));
out.write(CRLF);
out.flush();
`
I am currently implementing a game server manager for the RCON server protocol. I'm opening a connection to the server via a socket:
this.socket = new Socket();
this.socket.connect(new InetSocketAddress(this.getAddress(), this.getPort()), 3000);
The connection works fine, I can communicate with the server and receive the responses. No problem there. My problem is that when I am debugging the communication process and i take to long getting from the request to the read on the input stream, I am getting a message "Keep Alive". This is the code for request and response:
send:
Rcon rcon = new Rcon();
byte[] data = rcon.constructPackage(this.getPort(), pRequestType, pPayload);
OutputStream out = this.socket.getOutputStream();
out.write(data);
out.flush();
receive:
InputStream in = this.socket.getInputStream();
byte[] header = new byte[3*4];
in.read(header);
ByteBuffer buffer = ByteBuffer.wrap(header);
buffer.order(ByteOrder.LITTLE_ENDIAN);
int length = buffer.getInt();
int id = buffer.getInt();
int type = buffer.getInt();
int payloadLength = length - (2*4) - 2;
byte[] payload = new byte[payloadLength];
DataInputStream dis = new DataInputStream(in);
dis.readFully(payload);
dis.read(new byte[2]);
payloadString = new String(payload);
I have searched for this as Java and RCON related but I did not find a single clue where this is coming from. I'm guessing this is an RCON related effect, since I have to interpret the package which is received from the RCON server and split its contents to get to the actual payload. After this is done, the payload string contains "Keep Alive".
I am trying to send a simple message "Hi" to node server where I am using express and socket.io.
Here is how I am initializing my node server
var express = require('express');
var app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
server.listen(9001);
an I am trying to send the message from my java class as
Socket socket=new Socket("192.168.9.132", 9001);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("Hi");
socket.close();
I am not getting any console log at the node server end about getting message from socket.
Help how can I achieve this?
socket.io is a websocket, which is a different protocol/implementation than a usual socket. See the net library for TCP sockets.
I want to introduce SOA to a low latency system without the overhead of TCP communication(even on the same machine). Thirft seems like a great fit as I have both Java and php processes. Is there an IPC transport implementation for thrift, or any other good idea that could help in this scenario?
You could use Thrift to serialize your objects and then use IPC method of your liking(named pipe,message queues etc).
The following is a simple example using pipes
We have a an object of type Message which contains some information
Php process is the producer of the message
Java process is the consumer
Thrift model
struct Message {
1: i32 uid,
2: string information,
}
generate thrift sources
thrift --gen java message.thrift
thrift --gen php message.thrift
PHP producer
<?php
$GLOBALS['THRIFT_ROOT'] = 'src';
require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinarySerializer.php'; // this generates serialized string from our obect
require_once $GLOBALS['THRIFT_ROOT'].'/packages/message/message_types.php'; //from generated thrift sources
//create new message
$message = new Message();
$message->uid = '1';
$message->information = 'Some info';
var_dump($message);
//serialize
$serializer = new TBinarySerializer();
$serialized_message = $serializer->serialize($message);
var_dump($serialized_message);
//write to a pipe
if (pcntl_fork() == 0) {
$namedPipe = '/tmp/pipe';
if (! file_exists($namedPipe)) {
posix_mkfifo($namedPipe, 0600);
}
$fifo = fopen($namedPipe, 'w');
fwrite($fifo, $serialized_message);
exit(0);
}
?>
Java Consumer
//read from pipe
FileInputStream fileInputStream = new FileInputStream(new File("/tmp/pipe"));
int availableBytes = fileInputStream.available();
byte[] b = new byte[availableBytes];
fileInputStream.read(b , 0, availableBytes);
//deserialize
TDeserializer tDeserializer = new TDeserializer();
Message deserMessage = new Message();
tDeserializer.deserialize(deserMessage, b);
System.out.println(deserMessage.getInformation());
//prints "Some info"
See here regarding a cross-platform pipe transport for the Thrift C++ library. This should be straight-forward to port to the other languages. If you only need to support *NIX, you could use domain sockets which is already supported by TSocket. Simply pass in (name) instead of (host, port) to its constructor.
I suspect this has to do with endianness but I'm not sure how to fix it. I have a C++ client telling a Java server how many bytes it's about to send where the Java server just calls readInt() on the input stream. Then the server goes onto read the rest of the data.
At the moment if the C++ server calls:
char l = '3';
BytesSent = send( Socket, &l, 1, 0 );
Then the corresponding Java side is:
int lBytesSent = m_InDataStream.readInt();
m_AckNack = new byte[lBytesSent];
m_InDataStream.read(m_AckNack)
Bytes lBytesSent tends to be some massive value which then just throws an exception when it comes to creating the array (not surprisingly)
The C++ socket is simply opened up with:
Socket = socket(AF_INET, SOCK_STREAM, 0);
Option = 1000;
setsockopt(Socket, SOL_SOCKET, SO_RCVTIMEO, (char *) &Option, sizeof(Option));
server.sin_family = AF_INET;
server.sin_port = htons(Port);
server.sin_addr.s_addr = INADDR_ANY;
memset(&(server.sin_zero), '\0', 8);
connect(Socket, (sockaddr*)&server, sizeof(server));
And the Java side:
ServerSocket listener = new ServerSocket(port);
Socket server;
server = listener.accept();
Removing the error checking for clarity.
Any suggestions would be great
Many Thanks
Mark
Try running the number through htonl before sending it (on the C++ side):
long x = htonl(42); /* x now contains 42 represented in network byte order */