2013-02-12 11 views
5

具体的には、コンピュータにサーバ(java.net.ServerSocketインスタンス)がある場合、C#System.Net.Sockets.Socketインスタンスを使用してそのコンピュータに接続できますか?ソケットだけでJavaとC#の間で通信できますか?

+9

はい。彼らは言語に中立な読み込みバイト(JavaがC#のような 'バイト 'を符号なしに持っている面白い警告を除いて)に沸き立っています。 – pickypg

+1

はい、この回答(Blue Geneのもの)を見てください:http://stackoverflow.com/questions/5999180/sockets-send-strings-from-java-to-c – damix911

+0

@ damix911ディレクトリをリンクすることができます答え、例えば[Blue Gene's answer](http://stackoverflow.com/a/6001758/438992)。 –

答えて

23

主な問題は、送受信するデータのエンコーディングに非常に注意する必要があることです。一緒に働く一対のプログラムがあります。 C#クライアントは、最初に整数を長さとして送信し、文字列自体のバイトを送信することによって、文字列を送信します。 Javaサーバーは長さを読み取り、メッセージを読み取り、出力をコンソールに出力します。その後、エコーメッセージを作成し、その長さを計算し、バイトを抽出してC#クライアントに返します。クライアントは長さとメッセージを読み取り、出力を出力します。ビットごとのものをすべて避ける方法があるはずですが、正直言って私はこのこと、特にJava側で少し錆びています。

A Javaサーバ:

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class JavaSocket { 

    public static void main(String[] args) throws IOException { 

     ServerSocket serverSocket = new ServerSocket(4343, 10); 
     Socket socket = serverSocket.accept(); 
     InputStream is = socket.getInputStream(); 
     OutputStream os = socket.getOutputStream(); 

     // Receiving 
     byte[] lenBytes = new byte[4]; 
     is.read(lenBytes, 0, 4); 
     int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) | 
        ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff)); 
     byte[] receivedBytes = new byte[len]; 
     is.read(receivedBytes, 0, len); 
     String received = new String(receivedBytes, 0, len); 

     System.out.println("Server received: " + received); 

     // Sending 
     String toSend = "Echo: " + received; 
     byte[] toSendBytes = toSend.getBytes(); 
     int toSendLen = toSendBytes.length; 
     byte[] toSendLenBytes = new byte[4]; 
     toSendLenBytes[0] = (byte)(toSendLen & 0xff); 
     toSendLenBytes[1] = (byte)((toSendLen >> 8) & 0xff); 
     toSendLenBytes[2] = (byte)((toSendLen >> 16) & 0xff); 
     toSendLenBytes[3] = (byte)((toSendLen >> 24) & 0xff); 
     os.write(toSendLenBytes); 
     os.write(toSendBytes); 

     socket.close(); 
     serverSocket.close(); 
    } 
} 

C#クライアント:

using System; 
using System.Net; 
using System.Net.Sockets; 

namespace CSharpSocket 
{ 
    class MainClass 
    { 
     public static void Main (string[] args) 
     { 
      string toSend = "Hello!"; 

      IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse("192.168.0.6"), 4343); 

      Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      clientSocket.Connect(serverAddress); 

      // Sending 
      int toSendLen = System.Text.Encoding.ASCII.GetByteCount(toSend); 
      byte[] toSendBytes = System.Text.Encoding.ASCII.GetBytes(toSend); 
      byte[] toSendLenBytes = System.BitConverter.GetBytes(toSendLen); 
      clientSocket.Send(toSendLenBytes); 
      clientSocket.Send(toSendBytes); 

      // Receiving 
      byte[] rcvLenBytes = new byte[4]; 
      clientSocket.Receive(rcvLenBytes); 
      int rcvLen = System.BitConverter.ToInt32(rcvLenBytes, 0); 
      byte[] rcvBytes = new byte[rcvLen]; 
      clientSocket.Receive(rcvBytes); 
      String rcv = System.Text.Encoding.ASCII.GetString(rcvBytes); 

      Console.WriteLine("Client received: " + rcv); 

      clientSocket.Close(); 
     } 
    } 
} 
+0

gjその仕事は、簡単な話を理解しようと多くの時間を節約しました – azuneca

+0

Javaは符号なし数値プリミティブを持っていますが、それは8ビットではなく16ビットです。古いお気に入りのcharは符号なし16ビットです結局のところ数です。これは、[Character.toChars(int)](https://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#toChars%28int%29)がcharの配列を返す理由です。全体的なUTF-16の嫌悪感のために。 –

関連する問題