Baca InputStream menggunakan Java Server Socket

1. Gambaran keseluruhan

Untuk menghantar dan menerima data melalui rangkaian, kami sering menggunakan soket. Soket hanyalah gabungan dari alamat IP dan nombor port, yang dapat secara unik mengenal pasti program yang berjalan pada mesin tertentu.

Dalam tutorial ini, kami akan menunjukkan bagaimana kami dapat membaca data yang dihantar kepada kami melalui soket.

2. Membaca Data Dari Soket

Mari kita anggap, kita mempunyai pemahaman asas mengenai pengaturcaraan soket.

Sekarang, kita akan menggali lebih dalam membaca data di port yang didengarkan oleh pelayan kita.

Pertama, kita perlu menyatakan dan memulakan pemboleh ubah ServerSocket, Socket, dan DataInputStream :

ServerSocket server = new ServerSocket(port); Socket socket = server.accept(); DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

Perhatikan bahawa kami telah memilih untuk membungkus InputStream soket dalam DataInputStream. Ini membolehkan kita membaca baris teks dan jenis data primitif Java secara mudah alih.

Ini bagus sejak sekarang, jika kita mengetahui jenis data yang akan kita terima, kita boleh menggunakan kaedah khusus seperti readChar (), readInt (), readDouble () , dan readLine ().

Walau bagaimanapun, boleh mencabar jika jenis dan panjang data tidak diketahui sebelumnya.

Sekiranya demikian, kita akan mendapat aliran bait dari soket, sebaliknya, menggunakan fungsi baca () tahap bawah . Tetapi, ada masalah kecil dalam pendekatan ini: Bagaimana kita mengetahui panjang dan jenis data yang akan kita peroleh?

Mari kita teliti senario ini di bahagian seterusnya.

3. Membaca Data Binari dari Socket

Semasa membaca data dalam bait, kita perlu menentukan protokol kita sendiri untuk komunikasi antara pelayan dan klien. Protokol termudah yang dapat kita tentukan disebut TLV (Type Length Value). Ini bermaksud bahawa setiap mesej yang ditulis ke soket adalah dalam bentuk Nilai Panjang Jenis.

Oleh itu, kami menentukan setiap mesej yang dihantar sebagai:

  • Watak 1 bait yang mewakili jenis data, seperti s untuk String
  • Bilangan bulat 4 bait yang menunjukkan panjang data
  • Dan kemudian data sebenar, yang panjangnya baru ditunjukkan

Setelah pelanggan dan pelayan membuat sambungan, setiap mesej akan mengikuti format ini. Kemudian, kami dapat menulis kod kami untuk menghuraikan setiap mesej dan membaca n bait data dari jenis tertentu.

Mari lihat bagaimana kita dapat melaksanakan ini dengan menggunakan contoh mudah dengan mesej String .

Pertama, kita perlu memanggil fungsi readChar () , untuk membaca jenis data dan kemudian memanggil fungsi readInt () untuk membaca panjangnya:

char dataType = in.readChar(); int length = in.readInt();

Selepas itu, kita perlu membaca data yang kita terima. Perkara penting yang perlu diperhatikan di sini ialah fungsi read () mungkin tidak dapat membaca semua data dalam satu panggilan. Oleh itu, kita perlu memanggil read () dalam gelung sementara:

if(dataType == 's') { byte[] messageByte = new byte[length]; boolean end = false; StringBuilder dataString = new StringBuilder(length); int totalBytesRead = 0; while(!end) { int currentBytesRead = in.read(messageByte); totalBytesRead = currentBytesRead + totalBytesRead; if(totalBytesRead =length) { end = true; } } }

4. Kod Pelanggan untuk Menghantar Data

Dan bagaimana dengan kod sisi pelanggan? Sebenarnya, ia cukup mudah:

char type = 's'; // s for string String data = "This is a string of length 29"; byte[] dataInBytes = data.getBytes(StandardCharsets.UTF_8); out.writeChar(type); out.writeInt(dataInBytes.length); out.write(dataInBytes);

Itu sahaja yang dilakukan oleh pelanggan kami!

5. Kesimpulan

Dalam artikel ini, kami membincangkan cara membaca data dari soket. Kami melihat fungsi yang berbeza yang membantu kami membaca data jenis tertentu. Kami juga melihat cara membaca data binari.

Pelaksanaan penuh tutorial ini boleh didapati di GitHub.