【问题标题】:C# Networking IssueC# 网络问题
【发布时间】:2012-02-13 06:51:28
【问题描述】:

我正在尝试创建一个程序,该程序允许用户将他们编写的某些第三方代码的 JAR 文件上传到在线服务器,然后接收返回的字符串消息作为响应。

在线服务器使用 Java 和标准 TCP Socket 网络进行编码。客户端使用了一个额外的软件,这意味着我必须使用 C# 作为文件上传器。我编写的代码包含在下面。在这个程序中,文件上传器工作正常,但由于某种原因,客户端在到达 input.ReadLine() 时会挂起,它应该从服务器接收字符串消息响应。

public static string sendFile(string filepath) {

    String response = "";

    // Get the file
    Stream fileStream = File.OpenRead(filepath);

    byte[] buffer = new byte[fileStream.Length];
    fileStream.Read(buffer, 0, buffer.Length);

    try {

        // Create the connection
        TCPClient client = new TCPClient("127.0.0.1", 21000);

        NetworkStream stream = client.GetStream();

        // Send the file to the server
        stream.Write(buffer, 0, buffer.Length);
        stream.Flush();

        // Receive a single string response from the server
        if (stream.CanRead) {

            StreamReader input = new StreamReader(stream);
            inputString = input.ReadLine();

        }

        input.Close();
        stream.Close();
        client.Close();

    }

    catch (IOException e) {

        print ("Error: " + e);

    }

    // Return the response message string
    return inputString;

}

我还尝试使用 StreamWriter 实现上面的代码,而不是直接从 NetworkStream 本身编写。不幸的是,StreamWriter 类没有发送字节数组的方法(只有一个字符数组)。我想知道问题是否是由于我直接调用 NetworkStream 的 Write 方法而不是使用 StreamWriter 引起的。

如果有人知道为什么上面的代码不起作用,请告诉我。或者,如果您有不同的解决方案允许我使用相同的 TCPClient 连接发送文件(字节数组)并接收回字符串消息,那么也请随时提及。

问候,

米达维。

【问题讨论】:

  • StreamReader.ReadLine 需要换行、回车或组合。服务器会发送这个吗?

标签: c# networking tcp networkstream


【解决方案1】:

readline 挂起是因为它只有在从服务器成功读取一行后才会返回,这是使用阻塞套接字的缺点。请确保您的服务器准确地发送了一行(以“\n”结尾的字符串

【讨论】:

  • 服务器使用 Java PrintWriter 的 println 方法发回字符串消息,因此行尾标志应该与字符串的其余部分一起发送。如果我用 StreamWriter.Write() 替换代码中的 NetworkStream.Write 方法,然后发送“Test\n”一切正常,(测试字符串由服务器接收,其响应字符串由客户端接收)。但是,我不能使用 StreamWriter 发送包含我的文件的字节数组。
  • 请发布您发送字符串的服务器代码。
  • 上面的代码接缝是正确的,这只是我们想要的服务器端代码。
【解决方案2】:

您的流是否以行尾结束? Readline 将阻塞,直到流结束或收到行尾字符。如果您的上传者没有终止字符串,它可能会像您所说的那样。

【讨论】:

  • 服务器使用 Java PrintWriter 的 println 方法发回字符串消息,因此行尾标志应该与字符串的其余部分一起发送。
【解决方案3】:

Checkout networkComms.net,一个开源 C# 网络通信库。一个演示最基本功能的简短示例here,希望不会过于复杂!您可能遇到的大多数问题都已经解决了,这可能会为您节省一些时间。

【讨论】:

    【解决方案4】:

    Readline 等待行尾 \r\n 但在 java 中,行尾默认为 \n。这可能是阻止您的通信的差异,但要确保您需要窥探网络活动,或者您可以使用不同的方法来读取数据。

    你可以尝试使用read方法:

    byte[] myReadBuffer = new byte[512];
    int numberOfBytesRead = 0;
    
    // Incoming message may be larger than the buffer size.
    do{
        numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);  
        // do something with data in myReadBuffer
    }
    while(stream.DataAvailable);
    

    【讨论】:

      猜你喜欢
      • 2011-12-04
      • 2015-06-02
      • 2016-03-15
      • 2019-12-18
      • 2011-06-01
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多