Tout d'abord, je ne suis absolument pas un programmeur réseau. Ce que j'essaie de faire, c'est une communication TCP/IP très simple entre un serveur Java et un client C#.
Serveur Java:
public void run(){
try {
// Ouvrir le socket serveur
_server = new ServerSocket(SERVER_PORT);
_client = _server.accept();
System.out.println("ComInterface: client connecté.");
// Attendre un flux de données client
while(true){
// Recevoir un message du client
BufferedReader is =
new BufferedReader(new InputStreamReader(_client.getInputStream()));
msg = is.readLine();
// Traiter le message
if(msg!=null){
System.out.println("ComInterface: Message Reçu : <" + msg + ">.");
processMessage(msg); // Méthode indépendante
}
else{
System.out.println("ComInterface: le client a fermé la connexion.");
_client.close();
_client = _server.accept();
System.out.println("ComInterface: client connecté.");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String msg){
try {
// Flux sortant
DataOutputStream os = new DataOutputStream(_client.getOutputStream());
os.writeBytes((String)(msg+"\n"+(char)13));
os.flush();
System.out.println("ComInterface: Message <" + msg + "> envoyé");
} catch (IOException e) {
// Bloc catch généré automatiquement
e.printStackTrace();
}
}
Et voici le client C#:
public class ComInterface : MonoBehaviour
{
public const String SERVER_IP = "127.0.0.1"; // Localhost
public const int PORT = 1100; // Port par défaut
public const int READ_BUFFER_SIZE = 5000; // 4.8828125 kilo-octets
private TcpClient _client;
private ASCIIEncoding _asen;
private byte[] _readBuffer;
private String _msg;
public Boolean connected { get; internal set; } // le setter est destiné à un usage interne uniquement
/**
* Initialiser les variables internes (buffer, socket...)
*/
public ComInterface()
{
connected = false;
_client = new TcpClient();
_asen = new ASCIIEncoding();
_readBuffer = new Byte[READ_BUFFER_SIZE];
_msg = String.Empty;
}
/**
* Se connecter au serveur à SERVER_IP:PORT
* Renvoie vrai si la connexion a réussi, ou faux en cas d'échec.
*/
public Boolean Connect()
{
try
{
_client.Connect(SERVER_IP, PORT);
connected = true;
Array.Clear(_readBuffer, 0, _readBuffer.Length);
Debug.Log("TCPClient: Connecté au serveur");
// Démarrer une lecture asynchrone en invoquant ReceiveComMessage
_client.GetStream().BeginRead(_readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(ReceiveComMessage), _client.GetStream());
}
catch (Exception ex)
{
Debug.Log("TCPClient: Impossible de se connecter au serveur - " + ex.Message);
connected = false;
}
// Renvoyer l'état de la connexion
return connected;
}
/**
* Recevoir un message de Communicator
*/
private void ReceiveComMessage(IAsyncResult ar)
{
int BytesRead;
String msg;
try
{
BytesRead = _client.GetStream().EndRead(ar);
if (BytesRead < 1)
{
// si aucun octet n'a été lu, le serveur est fermé.
Debug.Log("TCPClient: Le serveur est fermé (BytesRead<1)");
this.Disconnect();
return;
}
// Convertir le tableau d'octets dans lequel le message a été enregistré,
msg = Encoding.ASCII.GetString(_readBuffer);
Debug.Log("C# Message: \"" + msg + "\""); // Exemple de sortie dans le journal ci-dessous
BytesRead = 0;
Array.Clear(_readBuffer, 0, _readBuffer.Length);
// Démarrer une nouvelle lecture asynchrone dans readBuffer.
_client.GetStream().BeginRead(_readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(ReceiveComMessage), _readBuffer);
}
catch (Exception ex)
{
Debug.Log("TCPClient: Le serveur est fermé (Exception) : " + ex.Message + " voir " + ex.StackTrace);
this.Disconnect();
}
Le principal problème est que tous les messages arrivent incomplets. Voici la trace du journal:
C#: Message "{
C#: Message ""sender":"Bob"",
C#: Message ""recipient":",
etc...
Au lieu par exemple de
C#: Message "{"sender":"Bob","recipient":[1,2,3]}"
Je suis un peu perdu et j'aurais besoin d'aide pour résoudre cela. Merci beaucoup!