Проблема с сетью C#

Я пытаюсь создать программу, которая позволяет пользователям загружать файлы JAR для некоторого стороннего кода, который они написали, на онлайн-сервер, а затем получать в ответ сообщение String.

Онлайн-сервер закодирован с использованием Java со стандартной сетью TCP Socket. Клиент использует часть дополнительного программного обеспечения, что означает, что я должен использовать C# для загрузки файлов. Код, который я написал, приведен ниже. В этой программе загрузчик файлов работает нормально, но по какой-то причине клиент зависает, когда достигает input.ReadLine(), где он должен получить ответ на сообщение String от сервера.

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 не имеет метода отправки массива байтов (только массив символов). Мне интересно, вызвана ли проблема тем фактом, что я вызываю метод Write для NetworkStream напрямую, а не с помощью StreamWriter.

Если у кого-нибудь есть идеи, почему приведенный выше код не работает, сообщите мне об этом. В качестве альтернативы, если у вас есть другое решение, которое позволило бы мне отправить файл (массив байтов) и получить обратно строковое сообщение, используя то же соединение TCPClient, пожалуйста, также не стесняйтесь упоминать об этом.

С уважением,

Мидави.


person midavi    schedule 18.01.2012    source источник
comment
StreamReader.ReadLine ожидает перевод строки, возврат каретки или их комбинацию. Сервер отправляет это?   -  person Simon Mourier    schedule 18.01.2012


Ответы (4)


Строка чтения зависает, потому что она вернется только тогда, когда успешно прочитает строку с сервера, это недостаток использования блокирующих сокетов. Пожалуйста, убедитесь, что ваш сервер действительно отправляет строку (строку, заканчивающуюся на "\n"

person Keagan Ladds    schedule 18.01.2012
comment
Сервер отправляет обратно строковые сообщения, используя метод println Java PrintWriter, поэтому флаг конца строки должен быть отправлен вместе с остальной частью строки. Если я заменю метод NetworkStream.Write в своем коде на StreamWriter.Write(), а затем отправлю Test\n, все будет работать нормально (тестовая строка будет получена сервером, а ее ответная строка будет получена клиентом). Однако я не могу использовать StreamWriter для отправки массива байтов, содержащего мой файл. - person midavi; 18.01.2012
comment
пожалуйста, опубликуйте свой код сервера, который отправляет строку. - person Keagan Ladds; 19.01.2012
comment
приведенный выше код кажется правильным, это просто код на стороне сервера, который мы также хотели бы, пожалуйста. - person Keagan Ladds; 19.01.2012

Ваш поток завершается концом строки? Readline будет блокироваться до тех пор, пока поток не завершится или не получит символ конца строки. Если ваш загрузчик не завершает строку, это может действовать так, как вы говорите.

person Mark Smith    schedule 18.01.2012
comment
Сервер отправляет обратно строковые сообщения, используя метод println Java PrintWriter, поэтому флаг конца строки должен быть отправлен вместе с остальной частью строки. - person midavi; 18.01.2012

Ознакомьтесь с networkComms.net, библиотекой сетевого взаимодействия C# с открытым исходным кодом. Короткий пример, демонстрирующий самые основные функции здесь, надеюсь не слишком сложная! Большинство проблем, с которыми вы можете столкнуться, уже решены, и это может сэкономить вам время.

person MarcF    schedule 18.01.2012

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);
person Massimo Zerbini    schedule 18.01.2012