C++ 客户端和 C# 服务器之间通过网络流进行通信

我有一个小的 shell 程序,其中客户端是用 C++ 编写的,而服务器是用 C# 编写的。客户端应该只向服务器写一些 cmd 命令的 awnseres。除了一件事之外,一切都运行得很完美:服务器输出的都是垃圾!!


这是 C# 中的服务器:


    static NetworkStream Stream;

    static byte[] AWNSER = new byte[255];


    static void Main(string[] args)

    {

        TcpListener listen = new TcpListener(IPAddress.Any, 123);

        listen.Start();

        Stream = listen.AcceptTcpClient().GetStream();


        Stream.BeginRead(AWNSER, 0, 255, HNDLR, null);

        while (true)

        {

            var str = Console.ReadLine();

            byte[] MESSAGE = Encoding.UTF8.GetBytes(str + "&& cd");

            Stream.Write(MESSAGE, 0, MESSAGE.Length);

        }

    }

    static void HNDLR(IAsyncResult a)

    {

        Stream.EndRead(a);

        Stream.BeginRead(AWNSER, 0, 255, HNDLR, null);


        Console.WriteLine(Encoding.UTF8.GetString(AWNSER));

    }

这是 C++ 中的客户端代码


FILE *fp;

char AWNSER[255];

WSAData wsaData;

WORD DllVersion = MAKEWORD(2, 1);


if (WSAStartup(DllVersion, &wsaData) != 0) //no error

{

    cout << "Winsock startup failed";

}

SOCKADDR_IN addr;

int addrlen = sizeof(addr);

addr.sin_port = htons(123);

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = inet_addr("199.166.177.22");

SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL);

if (connect(Connection, (SOCKADDR*)&addr, addrlen) != 0)

{   /*ERROR*/

}

else

{

        fp = _popen("dir", "r");

        while (fgets(AWNSER, 255, fp) != NULL) {

            cout << AWNSER;

            send(Connection, AWNSER, 255, NULL);

            AWNSER[255];

        }

        _pclose(fp);

}


幕布斯6054654
浏览 340回答 1
1回答

牛魔王的故事

AWNSER即使没有完全填写,您的客户端也会发送整个数组。您应该只发送实际输入的内容。服务器输出它接收的任何内容,但不考虑它实际接收的字节数。您需要考虑接收到的字节数。TCP 是一种流传输。发送和读取之间没有一对一的关系。因此,您需要缓冲传入的数据,并以客户端可以在完成发送消息时发出信号的方式来构建数据,并且服务器可以知道一个完整的消息在哪里结束,下一个从哪里开始。在您的简单示例中,空终止符或换行符就足够了。不要显示部分字符串。等待一个完整的字符串到达,然后再显示它。否则,在解码尚未准备好解码的内容时,您可能会损坏数据。在您的服务器处理程序中,Stream.BeginRead()在调用Console.WriteLine(). 使用完后调用它AWNSER。否则,您可能AWNSER会在有机会使用它之前被覆盖。尝试更像这样的事情:服务器:static NetworkStream Stream;static MemoryStream Data;static byte[] AWNSER = new byte[256];static void Main(string[] args){&nbsp; &nbsp; TcpListener listen = new TcpListener(IPAddress.Any, 123);&nbsp; &nbsp; listen.Start();&nbsp; &nbsp; Stream = listen.AcceptTcpClient().GetStream();&nbsp; &nbsp; Data = new MemoryStream();&nbsp; &nbsp; Stream.BeginRead(AWNSER, 0, AWNSER.Length, HNDLR, null);&nbsp; &nbsp; while (true)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var str = Console.ReadLine();&nbsp; &nbsp; &nbsp; &nbsp; byte[] MESSAGE = Encoding.UTF8.GetBytes(str + "&& cd\n");&nbsp; &nbsp; &nbsp; &nbsp; Stream.Write(MESSAGE, 0, MESSAGE.Length);&nbsp; &nbsp; }}static void HNDLR(IAsyncResult a){&nbsp; &nbsp; int numRead = Stream.EndRead(a);&nbsp; &nbsp; if (numRead == 0) return;&nbsp; &nbsp; Data.Seek(0, SeekOrigin.End);&nbsp; &nbsp; Data.Write(AWNSER, 0, numRead);&nbsp; &nbsp; byte[] bytes = Data.GetBuffer();&nbsp; &nbsp; int idx = 0;&nbsp; &nbsp; int size = (int) Data.Length;&nbsp; &nbsp; while (idx < size)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; int found = Array.FindIndex(bytes, idx, size - idx, b => b == 0x0A);&nbsp; &nbsp; &nbsp; &nbsp; if (found == -1) break;&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine(Encoding.UTF8.GetString(AWNSER, idx, found-idx);&nbsp; &nbsp; &nbsp; &nbsp; idx = found + 1;&nbsp; &nbsp; }&nbsp; &nbsp; if (idx > 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Buffer.BlockCopy(bytes, idx, bytes, 0, size - idx);&nbsp; &nbsp; &nbsp; &nbsp; Data.SetLength(size - idx);&nbsp; &nbsp; }&nbsp; &nbsp; Stream.BeginRead(AWNSER, 0, AWNSER.Length, HNDLR, null);}客户:bool sendRaw(SOCKET skt, void *buf, int bufsize){&nbsp;&nbsp; &nbsp; char *p = (char*) buf;&nbsp; &nbsp; while (buflen > 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; int sent = send(skt, p, buflen, 0);&nbsp; &nbsp; &nbsp; &nbsp; if (sent == SOCKET_ERROR) return false;&nbsp; &nbsp; &nbsp; &nbsp; p += sent;&nbsp; &nbsp; &nbsp; &nbsp; buflen -= sent;&nbsp; &nbsp; }&nbsp; &nbsp; return true;}...FILE *fp;char AWNSER[256];WSAData wsaData;WORD DllVersion = MAKEWORD(2, 1);if (WSAStartup(DllVersion, &wsaData) != 0) //no error{&nbsp; &nbsp; cout << "Winsock startup failed";}SOCKADDR_IN addr;int addrlen = sizeof(addr);addr.sin_port = htons(123);addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("199.166.177.22");SOCKET Connection = socket(AF_INET, SOCK_STREAM, 0);if (Connection == INVALID_SOCKET){&nbsp; &nbsp; /*ERROR*/}&nbsp;else{&nbsp; &nbsp; if (connect(Connection, (SOCKADDR*)&addr, addrlen) != 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; /*ERROR*/&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; fp = _popen("dir", "r");&nbsp; &nbsp; &nbsp; &nbsp; while (fgets(AWNSER, 256, fp))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int len = strlen(AWNSER);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while ((len > 0) && ((AWNSER[len-1] == '\r') || (AWNSER[len-1] == '\n'))) --len;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AWNSER[len++] = '\n';&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cout.write(AWNSER, len);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!sendRaw(Connection, AWNSER, len)) break;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; _pclose(fp);&nbsp; &nbsp; &nbsp; &nbsp; //...&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; closesocket(Connection);}
打开App,查看更多内容
随时随地看视频慕课网APP