2

こんばんは、

奇妙な問題があります。私は Visual C# にはあまり詳しくありませんが、iOS アプリケーションとの通信を可能にする小さなソケット アプリケーションを作成する必要があります。データが受信されるたびにトリガーされる関数の下を確認してください。

public void onDataReceived(IAsyncResult asyn)
    {
        // Debug.WriteLine("Receiving Data");
        try
        {
            CSocketPacket socketId = (CSocketPacket)asyn.AsyncState;
            int iRx = 0;
            iRx = socketId.thisSocket.EndReceive(asyn);
            char[] chars = new char[iRx + 1];
            Decoder d = Encoding.UTF8.GetDecoder();
            int charLen = d.GetChars(socketId.dataBuffer, 0, iRx, chars, 0);
            System.String szData = new System.String(chars);
            Debug.WriteLine(szData);
            stringVar += szData;
            Debug.WriteLine(stringVar);
            szData = "";
            startWaitingForData(socketWorker);
        }
        catch (ObjectDisposedException)
        {
            Debugger.Log(0, "1", "\n onClientConnection: Socket has been closed!\n");
        }
        catch (SocketException error)
        {
            Debugger.Log(0, "1", error.ToString());
        }
    }

iPhone からソケット サーバーへのメッセージの送信はうまく機能します。しかし、問題があります。ae "Message Test" を送信すると、最初の Debug.WriteLine(szData) で文字が正しくログに記録されます。(byte は byte[1] に設定されているため、バイトごとに関数が呼び出されます)。ただし、szData を stringVar プロパティに追加すると、正しく機能しません。Debug.WriteLine(stringVar) は常に最初の文字のみをログに記録します。私の例では、('Message Test' ではなく) 'MMMMMMMMMMMM' をログに記録します。

ここで何が欠けているのかわかりません。どんな助けでも本当に感謝しています。

ありがとうございました :)

更新: 私の startWaitingForData 関数の下:

public class CSocketPacket
    {
        public System.Net.Sockets.Socket thisSocket;
        public byte[] dataBuffer = new byte[1];
    }

    public void startWaitingForData(System.Net.Sockets.Socket soc)
    {
        // Debug.WriteLine("Start waiting for data");
        try
        {
            if (workerCallBack == null)
            {
                workerCallBack = new AsyncCallback(onDataReceived);
            }
            CSocketPacket socketPacket = new CSocketPacket();
            socketPacket.thisSocket = soc;
            soc.BeginReceive(socketPacket.dataBuffer, 0, socketPacket.dataBuffer.Length, SocketFlags.None, workerCallBack, socketPacket);
        }
        catch (SocketException error)
        {
            Debugger.Log(0, "1", error.ToString());
        }
    }

iPhone の部分については、ASCII エンコーディングを使用します。

NSData *data = [[NSData alloc] initWithData:[message dataUsingEncoding:NSASCIIStringEncoding]];

stringVar は次のように定義されます。

private string stringVar;
4

2 に答える 2

1

これを理解するには、もっと多くの情報が必要だと思います。

しかし、iPhoneはどのエンコーディングを送信していますか?

また、iRxは読み取られたバイト数を提供しますが、UTF8はマルチバイトエンコーディングであるため、これは必ずしも読み取られた文字数と同じではないことに注意してください。

MSDNによると、GetCharCountメソッドを使用して、配列サイズを設定する必要のある文字数を取得する必要があります。

編集:@Pascal更新後

Skeet氏のコメントによると、これをデバッグするための完全なバージョンがなければ、問題が何であるかについての推測作業のみです。また、あなたの最初の説明

「メッセージテスト」を送信すると、最初のDebug.WriteLine(szData)が文字を正しくログに記録します

一度に1バイトしか送信しない場合、真に鳴らないように見えますか?

修正の試みとして、次のことをお勧めします。

  • バッファサイズを1バイトから256のようなより賢明なものに増やします。一度に1バイトを実行するように強制する理由はありますか?
  • onDataReceivedハンドラーがstartWaitingForDataを呼び出し、これがBeginRecieveを実行するという事実に、再帰の要素があります。受信の間にローカル変数などをリセットしていることを確認してください。

サーバーのエンコーディングである場合、iPhoneクライアントは実際にUTF8を使用している必要があることに注意してください。

于 2012-04-24T07:17:47.677 に答える
0

の最初のバイトだけを常に読んでいsocketId.dataBufferますか?

于 2012-04-24T16:47:32.770 に答える