std.socket

なんとなくIRC BOTが書きたくなったので、std.socketの練習ということで書きました。
ソケットとかTCP/IPとかよく分かってない子なので四苦八苦しながら書く羽目になりました。

import std.c.stdio;
import std.socket;

const char[] server = "irc.friend.td.nu";
const ushort port = 6668;
const char[][] msg = [
    "NICK dbot\n",
    "USER dbot 0 * dbot\n",
    "JOIN #dbot\n"
];

void main(){
    InternetHost host = new InternetHost();
    host.getHostByName(server);
    Socket soc = new TcpSocket();
    soc.blocking = false;
    InternetAddress address = new InternetAddress(host.name, port);
    soc.connect(address);

    SocketSet wset = new SocketSet();
    wset.add(soc);
    Socket.select(null, wset, null);
    
    for (int i = 0; i < 3; i++){
        printf("send %.*s", msg[i]);
        soc.send(msg[i]);
    }

    SocketSet rset = new SocketSet();

    while (1){
        rset.add(soc);
        Socket.select(rset, null, null);

        if (rset.isSet(soc)){
            char[1024] buf;
            int read = soc.receive(buf);
            if (read == 0){
                break;
            } else {
                char[] str = buf;
                str.length = read;
                printf("%.*s", str);
            }
        }
        rset.reset();
    }

    printf("end\n");
    soc.shutdown(SocketShutdown.BOTH);
    soc.close();
}

基本はSocket作ってSocketSetにつっこんで後はひたすらselect。
躓いたりしたところ。

  • 何から書き始めたらいいか分からない。
    • 情けない。一生懸命ここ読んで頑張った。
  • ws2_32.libのリンクをしてなくてエラー祭。
    • 情けない。shinhさんに「つかリンクエラー見たらそのくらいわかれよと」と言われる。
  • sendできない。
    • selectでsend可能になるまで待ってなかった。
  • Error: Socket select error
    • selectに渡したSocektSetは書き換えられることがわかってなかった…
    • ちゃんとresetしてaddしなおしましょう。
  • printf("%.*s", buf)したら大量のゴミ。
    • どうみても静的配列です本当にありがとうございました。上のコードにあるように弄って解決。
  • 文字化けする。

しかし何か適当なスクリプト言語でやれよ感がひしひしと。