70755


[過去の質問](https://stackoverflow.com/questions/63803995/about-the-issue-that-the-
character-string-is-broken-in-tcp-ip-communication-
betw)にあるように、TCP/IPでデータを送信すると、文字列が分割されて送信される場合があります。

理想的には、以下のようなデータを複数回送信した場合

[code]

    "startString___test1test2test3test4test5....test20___endString"
    
[/code]

以下のように、データが到着してほしいのですが、そうなりません。

[code]

    "startString___test1test2test3test4test5....test20___endString"
    "startString___test1test2test3test4test5....test20___endString"
    "startString___test1test2test3test4test5....test20___endString"
    
[/code]

実際には、以下のような不規則に分割されて文字列データが送信されてきます。  
到着順序は正しく送られてくるようです。

[code]

    "startString___test1"
    "test2test3test4test5....test20___endStringstartString___test1test2test3test4"
    "test5....test20___endStringstartString___"
    "test1test2test3test4"
    "test5....test20___endString"
    
[/code]

このような不規則に分割された文字列の中から、以下のような中間の文字列を取得するにはどのような記述を行うと良いでしょうか？

[code]

    "test1test2test3test4test5....test20"
    
[/code]

何の言語でも良いのですが、ライブラリ等をなるべく使わずに、どの言語でも使いまわしやすいようなコードの書き方が知りたいです...。

試しにPythonを使って以下のような形で書いてみたのですが、頭がこんがらがって理解できません。。

[code]

    testArray = ["startString___test1",
    "test2test3test4test5....test20___endStringstartString___test1test2test3test4",
    "test5....test20___endStringstartString___",
    "test1test2test3test4",
    "test5....test20___endStringstartString___test1test2test3test4test5....test20___endStringstartString___test1test2test3test4test5....test20___endString"]
    
    combineString = ""
    for test in testArray:
        combineString += test
        if "startString___" in combineString and "___endString" in combineString:
            printString = combineString.replace('startString___', '').replace('___endString', '')
            combineString = ""
            print(printString+"\n")
    
[/code]

※)送信元では、文字列の先頭は"startString___"で始まり、末尾は"___endString"で終わるような形で指定しているものとします。この先頭の末尾の文字列に関する条件については、もっとやりやすいものがあれば変更して頂いても構いません。

※)また、この例では常に中間の文字列が一定の文字数になっていますが、実際に使用する際には、文字数にはバラつきがあるため、文字数による取得といった方法は使えません。

追記)  
一定量のデータは変数として留めておくことが可能な環境を想定していますが、すべてのデータを受信し終わってから実行するのではなく、届いたデータを届いた後に、なるべく早くprintを実行したいと考えています。


CC BY-SA 4.0
2020-09-27T08:40:32.187
70749
2020-09-27T15:09:58.447
2020-09-27T12:53:57.417
34471
34471
question
python network tcp
不規則に分割されて送られてくる文字列から中間部分の文字列を抽出する方法


到着した文字列を、その順序で連結してゆく。

連結された文字列に含まれる  
`"___endStringstartString___"`  
を区切り文字（例えば、改行文字）に置換する。

そうすれば、データ部分が区切り文字で分けられた文字列になると思います。

通信の最初の"startString___"は無視するとか、  
`"___endStringstartString___"`を区切り文字（例えば、改行文字）に置換するのは、連結した文字列が充分な長さ(少なくとも１つのデータ部分が含まれる長さがある）になった時に限るとか、細かい工夫を加える必要があるでしょう。


CC BY-SA 4.0
2020-09-27T08:58:34.097
70751
2020-09-27T08:58:34.097
217
70749
answer


（コメント内容からアップデートしています）  
やりたいのはこんな感じでしょうか？  
ちょっと分かりやすさと説明のためにtestArrayの内容も変えています）

[code]

    testArray = ["startString___test1",
    "___endStringstartString___test1test2",
    "___endStringstartString___",
    "test1test2test3",
    "___endString",
    "startString___test1test2test3test4___endString",
    "startString___test1test2test3tes",
    "t4test5___en",
    "dStringst",
    "artString___",
    "___endString",
    "startString___test1test2test3test4",
    "test5....test7___endStringstartString___test1test2test3test4test5....test8___endStringstartString___test1test2test3test4test5....test9___endString"]
    
    combineString = ""
    for test in testArray:
        combineString += test
        if "startString___" in combineString:
            combineString = combineString.replace("startString___","")
        splited = combineString.split("___endString")
        splited_len = len(splited)
        if splited_len==1:
            continue
        counter = 0
        for i in splited:
            combineString = i
            counter += 1
            if counter < splited_len:
                print(combineString)
                combineString = ""
    
[/code]

処理としてはテキストをバッファリングして溜め、"___endString"の度にprintしています。testArrayの中に"___endString"は全部で9個あります。

"startString___"は常に要らないのでバッファする内容に含めません。  
ですが、testArrayに追加したような途中で切れたテキスト"artString___"等にも対応するために、バッファしたテキストにデータを足し合わせてから削除を行っています。

このコードを実行すると分かりますが、testArrayに内容が空のデータも入っており、その場合は空文字がプリントされるので、出力したくない場合はprintの前で条件分岐しコントロールすると良いと思います。


CC BY-SA 4.0
2020-09-27T11:45:39.687
70755
2020-09-27T15:09:58.447
2020-09-27T15:09:58.447
8795
8795
70749
answer