Internet commandはまだ非unicodeプラグインでしょうか

ここのhttp://forums.4d.com/Post/JP/7013484/1/7013485過去ログ>に非unicodeプラグインだと書いてありました。
2011年ごろで4Dがv11でのお話の様なのですが、いまでもそうなのでしょうか?
また、IPv6には対応しているのでしょうか。

ドキュメントを探してみたのですが、それについて触れている部分を見つけることができませんでした。

よろしくお願いします。 :pray:

「プラグインがUnicodeかどうか」を判断する上では,幾つかの材料を考慮する必要があります。

まず,MSVCのUNICODEフラグは無関係です。(Wで終わるAPIを直接コールすれば良い)

SDKのエントリーポイントについていえば,FourDPack(非Unicode)とFourDPackex(Unicode)の両方が渡され(非UnicodeのストラクチャでUnicodeのプラグインを使用したり,その逆のことができるのは,このためです),相互に排他的ではないので,Unicode(非Unicode)版のプラグインである,と断定することはできません。

実用的なことでいえば,

  1. 引数をどちらのエントリーポイントで受け取っているか
  2. 内部的にUnicode版のAPIを使用しているか

が鍵となります。

非Unicodeのエントリーポイントで引数を受け取れば,ストラクチャがUnicodeモードであっても,エンコーディングはANSIに変換され,32Kバイトで切り捨てられます。v11のInternet Commandsは,そうでした。

v14のドキュメントに「Internet CommandsがUnicodeになった」と記述されていますが,これは,引数をFourDPackexのエントリーポイントで受け取っているという意味です。

http://library.4d-japan.com/REFERENCE/v14/4d-upgrade-14.pdf

304ページ

しかし,引数がUnicodeで渡されているのと,内部的にUnicode版のAPIを使用しているのとは別問題です。

4D Internet Commandsは,サードパーティ製のソフトウェアを無料で適用できるよう,昔,4Dが買い取ったものですが,ファイル関係のAPIは,Carbon/Alturaの古いAPI(fsspecs, fsref)が各所で使用されていました。

16R2のInternet Commandsでは,ファイル関係のAPIを両プラットフォームともに,Unicodeに対応したものに書き換えられています。これは,14R4(Mac)の64ビット版で先行して始まった作業を完了するものです。

R版のInternet Commandsでは,その後もUnicode関係のバグが幾つか修正されており,ライセンスの例外として,15.xや16.xでも使用できるようになっています。

しかし,Carbon/Alturaの古いAPI(fsspecs, fsref)を切り捨てたことにより,以前の「仕様」の幾つかが失われました。

たとえば:

カレントパス(ショートパス)の概念

ファイル名だけを指定した場合,実行ファイル(4D)と同じディレクトリを指すことになります。
以前はデータベースフォルダーでした。

パスの長さ

以前は62文字まででしたが,16R2では,32/64ビットともに両プラットフォームで1024文字に拡張されます。

なお,16.xの32ビット版は,互換性を優先するため,古いファイルAPIを引き続き使用しています(パスの長さは62文字まで)。

FTPのプログレスバー(Mac)や,空のパスを指定した場合に表示されたファイル選択ダイアログは,使えなくなりました。
(古いファイルAPIの振る舞いに依存していたため)

古いエンコードアルゴリズムであるAppleSingleとAppleDoubleは使えなくなりました。

ただし,FTPのプログレスバーについては,将来,再開発されるかもしれません。

まとめ

16.xは,互換性を重視するため,ファイル関係のAPIが部分的にUnicodeに非対応です。

16Rでは,ファイル関係のAPIが新しいものに切り替わっているので,フルパスを指定する限り,Unicode対応ということができますが,それと引き換えに,幾つかの機能は使用できなくなりました(エラーは返されず,ただ「何も起こらない」)。

ご回答ありがとうございます。

まだ完全に対応というわけではないんですね。

久しぶりにTCP_Sendを使ってみたのですがテキストデータが32Kの制限がかかったままの様です。
プラグインの引数としてテキストの32Kの制限は大分前に解除されたはずだと記憶していたので
制限が残っているのが仕様なのかバグなのか判断できませんでした。
調べていくと、プラグイン自体がunicode対応かどうかハッキリしない状態になったので質問しました。

32Kの制限を残す互換性上の問題はないと思います。なのでバグだと思うのですが… :frowning:

非Unicode時代は,テキストにバイナリデータを収容することが,結構,普通に行われていました。

TCPのSendとReceiveは,UTF-16(テキスト)ではなく,バイトの配列を送受信するわけですから,
互換性を維持するためには,内部的にTEXT TO BLOBをコールする必要がありますし,
互換コードであれば,32K未満のASCII(あるいはANSI)データを想定しているはずですから,
32Kで切り捨てられるのは,仕様どおりということにならないでしょうか。

Unicodeモードあれば,エンコーディングを明確にして,BLOBに変換することが必須になるかと思います。

: Keisuke MIYAKO

非Unicode時代は,テキストにバイナリデータを収容することが,結構,普通に行われていました。

TCPのSendとReceiveは,UTF-16(テキスト)ではなく,バイトの配列を送受信するわけですから,
互換性を維持するためには,内部的にTEXT TO BLOBをコールする必要がありますし,
互換コードであれば,32K未満のASCII(あるいはANSI)データを想定しているはずですから,
32Kで切り捨てられるのは,仕様どおりということにならないでしょうか。

Unicodeモードあれば,エンコーディングを明確にして,BLOBに変換することが必須になるかと思います。

確認です。TEXT TO BLOBのドキュメントを読んで気がついたのですが、もしかしてTCP_Sendは内部でANSIに変換しているのでしょうか?そうするとunicodeにしか無い文字などは文字化けしてしまうと思うのですが?

後、非unicodeの互換と言うことだと4D2004あたりまで遡らないといけないのですがこれって重要でしょうか?
4D以外の環境との送信と言うことであれば、逆にTCP_SendBLOBを使う様に進めるのが正解ではないかと思います。

TCP_SendBLOB, TCP_ReceiveBLOBの使用を推奨するよう,ドキュメントの担当者に追記を依頼しました。

非Unicodeモードとの互換性についてですが,4D Internet Commandsそのものが「(v2004よりも昔に書かれた)古いメソッドを生かし続けること」をおもな目的としたプロジェクトであり,(今やUnicodeモードが大前提である)本体に統合されることも,新コマンドが追加されることもなく,不具合の修正を続けている事情があります。ファイルパスに関する「改善」も,64ビット版を提供するにあたり,やむなく必要となったリファクタリングの副産物に過ぎず,当該プラグインに依存しているアプリケーションの_互換性を維持することを別にすれば_,10年以上前から4D Internet Commandsの開発にはまったく力を入れていない,といっても過言ではないかもしれません。

補足:

少し前のブログで,TLS関連の「セキュリティ強化」が取り上げられましたが,

https://blog.4d.com/higher-security-ranking-for-4d-web-sites/

4D Internet Commandsは_Min TLS version_ (105) の対象外となっています。

http://doc.4d.com/4Dv16R5/4D/16-R5/SET-DATABASE-PARAMETER.301-3481818.ja.html

(OpenSSLライブラリは共有ですが,本体とは別の"ネットワークレイヤー"を有しているため)

TEXT TO BLOBのtextFormatをMac text without lengthをUTF8 text without lengthに置き換えるだけかと思ったのですが、そこまでメンテナンスしたく無いのであれば、TCP_Send/TCP_Reciveは廃止の方向でよいのでは?:roll:

率直なご意見ありがとうございます。

世界的にみれば,ASCIIだけで動いている4Dアプリケーションが相当な割合を占めており,
UTF-8よりもMacRomanのほうが望ましい場合もありますので,
TCP_Send/TCP_Receiveには,一定のニーズがあるのだと思います。

メンテナンスを_したくない_というよりも,
Internet Commandsの保守は,4Dの開発と保守からかなりの工数を奪うものなので,
必要最低限のものに_せざるを得ない_,というのが現状です。

: Keisuke MIYAKO

率直なご意見ありがとうございます。

世界的にみれば,ASCIIだけで動いている4Dアプリケーションが相当な割合を占めており,
UTF-8よりもMacRomanのほうが望ましい場合もありますので,
TCP_Send/TCP_Receiveには,一定のニーズがあるのだと思います。

メンテナンスを_したくない_というよりも,
Internet Commandsの保守は,4Dの開発と保守からかなりの工数を奪うものなので,
必要最低限のものに_せざるを得ない_,というのが現状です。
まあどちらでもいいんですが :mrgreen:

TCP_Send/Reciveのドキュメントに
1.32Kの制約がある事
2.ANSIに変換して送っている事
を明記してください。
その上でTCP_SendBLOB/ReciveBLOBをオススメする様にリンクをつけておいてください。

ドキュメントを見ても状況がわからないのは困ります。

かしこまりました。

ドキュメントの担当者には,32Kの件,ANSIの件,BLOBの件,と伝えました。

内容が正確であることを,開発チームがチェックした上で,更新されることになります。

Ahora estoy probando con un medidor de caudal pero si funciona habrá más de 5.

El medidor emite los datos a un ordenador cada 15 minutos, pero los minutos no coinciden. No puedo establecer un tiempo.

Así que tengo que leer los datos continuamente y verificar si recibo los datos. Finalmente leer el Telegram MBUS y entrar los datos en 4D.

Ahora utilizo la versión V15, pero puedo cambiar a la V16 sin problemas.

No tengo que enviar ninguna petición al medidor, no es maestro/esclavo. Funciona vía radio y emite la señal a un convertidor MBUS/Ethernet. El convertidor envía la señal a un ordenador que hemos configurado la IP.

Si hay 5 aparatos uno lo puede enviar en el minuto 5, el otro en el 15, etc… Así que tiene que estar siempre conectado. Por eso pensaba en TCP_Listen o UDP.

¿TCP_Listen lo tengo que tener siempre actuando o tengo que activarlo y cerrarlo cada X Ticks para poder recibir los datos?

En ese caso sí es mejor usar TCP_Listen. Sencillamente, en un proceso aparte lo dejas activado. Al ejecutar TCP_Listen el proceso quedará en espera hasta recibir una petición. Pienso que es mejor que espere indefinidamente de lo contrario sería difícil coordinar los tiempos de envío con los tiempos de recibo.

$err:=TCP_Listen("";0;502;30;vTCPID) // Tiempo de espera de 30 segundos

$err:=TCP_Listen("";0;502;0;vTCPID) // Tiempo de espera indefinido, la ejecución continúa al recibir una petición

Una vez abierto para leer los datos utilizo TCP_Receive siguiendo el ejemplo:

C_LONGINT($tcp_id)
C_TEXT($webpage;$buffer)
C_INTEGER(vState;$error)

$webpage:=""
vState:=0

Repeat
$error:=TCP_Receive($tcp_id;$buffer)
$error:=TCP_State($tcp_id;vState)
$webpage:=$webpage+$buffer
Until((vState=0)|($error#0))hasta que el servidor cierre la conexión o se presente un error

Así es. Solo que en este caso todo debe ir en un bucle. Terminando con TCP_Close y volviendo a TCP_Listen

Gracias, voy a probar.

:mrgreen:

En este caso que es mejor, ¿Utilizar un bucle mediante Repeat o SET TIMER?

Gracias de nuevo.

:wink:

Repeat con DELAY PROCESS en un proceso aparte.

SET TIMER se usa solo con formularios, si se cierra el formulario dejas de recibir los datos.