TCPSocketConnection で作成したソケットオブジェクトのローカルポート番号を指定したいがbindが使えない

22 Jul 2015

簡易FTPサーバーを作っていまして、サーバー側からデータ転送コネクションとしてローカルポートを指定したうえでクライアントにリンクを張るのですが、bind()を使えないので(TCPSocketConnectionのメンバ関数として用意されていない)ので困っています。ライブラリ自作付加を試みましたが迷い森に入り頓挫しました。何かいい実現方法は無いでしょうか。なお、今のところはmbed標準ライブラリの一部である "EthernetInterface.h"を使用しています。

22 Jul 2015

Socketを使うなら指定できると思うのですが、勘違いならすみません。

https://developer.mbed.org/handbook/Socket

すみません違いますね。削除します。

23 Jul 2015

TCPSocketServerでは、bindでinit_socketをしていて、このbind断片コードををそのままTCPSocketConnectionに持ってきてもconnectでinit_socketしているので重複して駄目でした。 そこで、TCPSocketConnectionのconnectを拡張して、localportを与えられるようにしたところうまくいきました。

modified TCPSocketConnection::connect

int TCPSocketConnection::connect(const char* host, const int port, const int localport) {
    if (init_socket(SOCK_STREAM) < 0)
        return -1;

    struct sockaddr_in localHost;
    memset(&localHost, 0, sizeof(localHost));
    
    localHost.sin_family = AF_INET;
    localHost.sin_port = htons(localport);
    localHost.sin_addr.s_addr = INADDR_ANY;
    
    if (lwip_bind(_sock_fd, (const struct sockaddr *) &localHost, sizeof(localHost)) < 0) {
        close();
        return -1;
    }
--SNIP--

本当は初期化済をチェックしてconnectとbindのどちらかでinit_socketをすべきかと思います。 まあ、取りあえずです。

23 Jul 2015

どうやら、以下の変更でbind()がokのようです。wiresharkで確認しました。

TCPSocketConnection class added bind()

int TCPSocketConnection::connect(const char* host, const int port) {
    if (_sock_fd == -1){
	    if (init_socket(SOCK_STREAM) < 0)
	        return -1;
    }

    if (set_address(host, port) != 0)
        return -1;
    
    if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
        close();
        return -1;
    }
    _is_connected = true;
    
    return 0;
}


int TCPSocketConnection::bind(int port) {
    if (_sock_fd == -1){
        if (init_socket(SOCK_STREAM) < 0)
            return -1;
    }

    struct sockaddr_in localHost;
    memset(&localHost, 0, sizeof(localHost));
    
    localHost.sin_family = AF_INET;
    localHost.sin_port = htons(port);
    localHost.sin_addr.s_addr = INADDR_ANY;
    
    if (lwip_bind(_sock_fd, (const struct sockaddr *) &localHost, sizeof(localHost)) < 0) {
        close();
        return -1;
    }
    
    return 0;
}

一人で騒いでゴメンナサイ