Ae pessoal. Eu tô querendo fazer um esquema pra facilitar a comunicação entre programas Java com C++. Eu já li um pouco sobre JNI, mas conversando com algumas pessoas veio a idéia q usar rede pode ser mais fácil.
Meu objetivo específico pro momento é desenvolver a lógica em Java e usar o CBuilder pra fazer a GUI, em vez de usar Swing. Mas eu queria aproveitar pra fazer alguma coisa q já fosse pra uso geral.
A idéia é fazer a lógica toda indepentende da interface com usuário. Daí qd ela tivesse pronta (ou pelo menos bem documentada), em vez de usar Swing pra fazer a GUI fizesse uma interface em rede, com um protocolo simples. Toda a troca de informações seria via XML, assim o client só ia precisar ter suporte a socket e um XML Parser razoável.
Blz, eu comecei a ler sobre Socket em Java e fiz 2 aplicações exemplo de servidor e client, elas funcionam de acordo.
Daí eu li uns tutoriais sobre Winsocks e fiz um client C++. Só q na hora de ler os dados o servidor desconecta e levanta uma Exception falando q ele resetou
Analisando um pouco (comentando códigos e vendo resultado) eu vi q o client C++ conecta sem problema no server, o problema é qd ele manda uma string e o server tenta ler.
Alguém tem idéia de como enviar strings em C++ pra Java?
Em java eu usei a classe String e em C++ usei array de char, tudo tradicional. Tentei uma um esquema mais baixo nível em Java lendo arrays de bytes mas deu o mesmo erro…
Segue o código se alguem tiver vontade de olhar oq eu já consegui.
O Server Java só suporta 1 client, qd um client conecta ele entra em loop lendo uma linha e imprimindo ela no stdout; qd ele recebe a string “finish” ele sai do loop e fecha; se passar 10s sem receber nenhuma mensagem ele expira e recomeça o loop; eu fiz um contador só pra ficar fácil ver q o loop tá acontecendo.
O Client Java conecta no server e fica esperando entrada no prompt, toda string q ele recebe ele manda pro server, qd ele recebe a string “finish” ele manda ela pro server (pra q ele feche) e fecha tb.
Essas 2 classes tão se comunicando sem problema.
[code]import java.io.;
import java.net.;
public class Server {
public static void main(String[] args) {
//Declaro o ServerSocket
ServerSocket serv=null;
//Declaro o Socket de comunicação
Socket s= null;
//Declaro o leitor para a entrada de dados
BufferedReader entrada=null;
try{
//Cria o ServerSocket na porta 7000 se estiver disponível
serv = new ServerSocket(7000);
//Aguarda uma conexão na porta especificada e cria retorna o socket que irá comunicar com o cliente
String string;
s = serv.accept();
s.setSoTimeout(10000);
int i=0;
//Cria um BufferedReader para o canal da stream de entrada de dados do socket s
entrada = new BufferedReader(new InputStreamReader(s.getInputStream()));
do{
try{
string=entrada.readLine();
if(string!=null && string.trim().equals("finish")) break;
//Aguarda por algum dado e imprime a linha recebida quando recebe
System.out.println(string);
}catch(java.net.SocketTimeoutException ex){
ex.printStackTrace();
}
System.out.println("\n"+(i++)+"\n");
}while(true);
//trata possíveis excessões de input/output. Note que as excessões são as mesmas utilizadas para as classes de java.io
}catch(IOException e){
//Imprime uma notificação na saída padrão caso haja algo errado.
e.printStackTrace();
}finally{
try{
//Encerro o socket de comunicação
s.close();
//Encerro o ServerSocket
serv.close();
}catch(IOException e){
}
}
}
}
[/code]
[code]import java.io.;
import java.net.Socket;
import java.util.;
public class Client {
public static void main(String[] args) {
//Declaro o socket cliente
Socket s = null;
//Declaro a Stream de saida de dados
PrintWriter pw = null;
try{
Scanner sc = new Scanner(System.in);
String string;
//Cria o socket com o recurso desejado na porta especificada
s = new Socket("127.0.0.1",7000);
//Cria a Stream de saida de dados
pw = new PrintWriter (s.getOutputStream(), true /*autoflush*/);
do{
string=sc.next();
pw.println(string);
if(string!=null && string.trim().equals("finish")) break;
}while(true);
//Trata possíveis exceções
}catch(IOException e){
e.printStackTrace();
}finally{
try{
//Encerra o socket cliente
s.close();
}catch(IOException e){}
}
}
}
[/code]
O Client C++ foi compilado usando o “Borland C++ 5.6 for Win32” (eu tentei compilar ele usando o Dev-C++ e akele compilador bugado naum conseguiu linkar). Ele compila sem erro e executa sem erro tb. Eu fiz um loop pra testar o envio de várias mensagens, ele diz q todas foram enviadas mas o server naum imprime nenhuma e qd ele fecha a conexão o server levanda a “java.net.SocketException: Connection reset”.
Isso leva a 2 problemas:
- Se o client diz q as mensagens tão sendo enviadas, pq o server não imprime elas?
- A exception Connection reset tá sendo levantada pelo server qd o client desconecta. Como seria a forma certa de desconectar então?
[code]#include <stdio.h>
#include “winsock2.h”
void main() {
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
// Create a socket.
SOCKET m_socket;
m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( m_socket == INVALID_SOCKET ) {
printf( "Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return;
}
// Connect to a server.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
clientService.sin_port = htons( 7000 );
if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
printf( "Failed to connect.\n" );
WSACleanup();
return;
}
// Send and receive data.
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[32] = "Client: Sending data.";
char recvbuf[32] = "";
for(int i=0;i<5;i++){
bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
printf( "Bytes Sent: %ld\n", bytesSent );
}
WSACleanup();
return;
}[/code]