Qiita初投稿です。よろしくおねがいします。
C#ばかり書いていましたが最近Kotlinをはじめました。いいですよね、Kotlin。擬人化したら絶対に可愛いです。
#UDP通信をしようとしたら困った
簡単な文字列を受信し、ByteArray->Stringに変換してコンソールに写すだけです。(通信に関しては今回は触れません)
で、"finish"という文字列を受信したら通信をやめる、そんな感じにしたかったんです。したかったんです。
#同じ文字列なのに等しいと判断されない…
うまくいかなかったときのソースコードは以下の通りです。
import Mylib.Udp.UdpConnection //自作のUdp通信クラス
import java.nio.charset.Charset
fun main(args: Array<String>)
{
val port = 2222
val bufferSize = 16
val udp = UdpConnection(port, bufferSize)
var received: String? = null
println("Start")
while (received != "finish")
{
received = udp.receive().toString(Charset.defaultCharset())
println(received)
}
}
package Mylib.Udp
import java.io.FileWriter
import java.io.PrintWriter
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.nio.charset.Charset
class UdpConnection(private val port: Int, private val bufferSize:Int)
{
fun receive(): ByteArray
{
val socket= DatagramSocket(port)
val data = ByteArray(bufferSize)
var packet: DatagramPacket? = null
try
{
packet = DatagramPacket(data, data.size)
socket.receive(packet)
}
catch (e: Exception)
{
println(e.message)
}
socket.close()
return data
}
}
これを実行中に"fnish"と三回送ったとします。私としてはコンソールには"Start"の後に一度だけ"finish"と出てきて終わっていただきたい。しかし、結果は…
Start
finish
finish
finish
?????????なんですか??これ
いや、まぁ、文字化けしてるとかならわかるんですよ。
最初はJavaで有名な"=="と"equals"の違いが原因かと思いました。しかし、Kotlinでは参照先の比較は"==="で値の比較は"=="となっているため、今回は関係なさそうです。他にも文字コードや送信機などを疑ってみましたがどれも見当違い…
#結局どうしたか
まず、以下の拡張関数を定義しました。
fun ByteArray.createString(packet: DatagramPacket) = String(this, 0, packet.length, Charset.defaultCharset())
そして上記のreceiveメソッドの型をString?に変更し、リターン部分を下記のように変更しました。
return if (packet != null) data.createString(packet); else null
結果、意図していた動作をしましたが、なぜ前のコードがダメだったのかはわかりません(わかる方いらっしゃいましたらご教示ください)
#最後に
初投稿のため、拙い部分やおかしな部分もあると思いますが、閲覧頂きありがとうございます。関係ないですが、C#では下記のように簡単に実装できたため、Udp通信のハローワールド的なプログラムでつまずくと思いませんでした…
using System;
using System.Net.Sockets;
using System.Text;
class Program
{
static void Main(string[] args)
{
var Receiver = new UdpClient(2222);
var ReceivedStr = string.Empty;
Console.WriteLine("Start");
while ((ReceivedStr = Encoding.UTF8.GetString(Receiver.ReceiveAsync().Result.Buffer)) != "finish")
Console.WriteLine(ReceivedStr);
}
}
ここまで言ってJavaの使いやすいUdpライブラリがあったら恥ずかしいですね。(でもあったら使いたいです)