Сокеты в C#: Как получить ответный поток?

Со знанием дела Кристофера Джонса мне удалось как-то решить проблему. Поскольку у меня нет полного контроля над рабочей машиной, было немного трудно выполнить нормальную установку.

Когда я работал с NodeJS 9.20, библиотека oracledb не поддерживала (не содержала предварительно собранные двоичные файлы для этой версии) с общей установкой с использованием npm install oracledb. Что еще хуже, у меня не было установленного Python, оставив компиляцию исходного кода для генерации двоичных файлов в качестве опции.

Вместо этого выполнили следующие шаги, чтобы решить проблему.

  1. Скачанные файлы oracledb.2.2.0.tgz и oracledb-v2.2.0-node-v59-win32-x64
  2. Извлеките и скопируйте файл oracledb.node в папку / build / Release
  3. Включите ссылку в источнике код

Для получения дополнительной информации см. Ручное извлечение node-oracledb для получения дополнительной информации.

Надеюсь, это поможет.

10
задан 4 revs 9 February 2009 в 12:21
поделиться

3 ответа

Вот некоторый код, который работает на меня.

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO.Compression;

namespace HttpUsingSockets {
    public class Program {
        private static readonly Encoding DefaultEncoding = Encoding.ASCII;
        private static readonly byte[] LineTerminator = new byte[] { 13, 10 };

        public static void Main(string[] args) {
            var host = "stackoverflow.com";
            var url = "/questions/523930/sockets-in-c-how-to-get-the-response-stream";

            IPHostEntry ipAddress = Dns.GetHostEntry(host);
            var ip = new IPEndPoint(ipAddress.AddressList[0], 80);
            using (var socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) {
                socket.Connect(ip);
                using (var n = new NetworkStream(socket)) {
                    SendRequest(n, new[] {"GET " + url + " HTTP/1.1", "Host: " + host, "Connection: Close", "Accept-Encoding: gzip"});

                    var headers = new Dictionary<string, string>();
                    while (true) {
                        var line = ReadLine(n);
                        if (line.Length == 0) {
                            break;
                        }
                        int index = line.IndexOf(':');
                        headers.Add(line.Substring(0, index), line.Substring(index + 2));
                    }

                    string contentEncoding;
                    if (headers.TryGetValue("Content-Encoding", out contentEncoding)) {
                        Stream responseStream = n;
                        if (contentEncoding.Equals("gzip")) {
                            responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                        }
                        else if (contentEncoding.Equals("deflate")) {
                            responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                        }

                        var memStream = new MemoryStream();

                        var respBuffer = new byte[4096];
                        try {
                            int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
                            while (bytesRead > 0) {
                                memStream.Write(respBuffer, 0, bytesRead);
                                bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
                            }
                        }
                        finally {
                            responseStream.Close();
                        }

                        var body = DefaultEncoding.GetString(memStream.ToArray());
                        Console.WriteLine(body);
                    }
                    else {
                        while (true) {
                            var line = ReadLine(n);
                            if (line == null) {
                                break;
                            }
                            Console.WriteLine(line);
                        }
                    }
                }
            }
        }

        static void SendRequest(Stream stream, IEnumerable<string> request) {
            foreach (var r in request) {
                var data = DefaultEncoding.GetBytes(r);
                stream.Write(data, 0, data.Length);
                stream.Write(LineTerminator, 0, 2);
            }
            stream.Write(LineTerminator, 0, 2);
            // Eat response
            var response = ReadLine(stream);
        }

        static string ReadLine(Stream stream) {
            var lineBuffer = new List<byte>();
            while (true) {
                int b = stream.ReadByte();
                if (b == -1) {
                    return null;
                }
                if (b == 10) {
                    break;
                }
                if (b != 13) {
                    lineBuffer.Add((byte)b);
                }
            }
            return DefaultEncoding.GetString(lineBuffer.ToArray());
        }
    }
}

Вы могли заменить этим Socket/NetworkStream и сохранить немного работы.

using (var client = new TcpClient(host, 80)) {
      using (var n = client.GetStream()) {
     }
} 
11
ответ дан 3 December 2019 в 20:44
поделиться

Сокет, по определению, является низким уровнем для доступа к сети. Можно даже использовать датаграммные протоколы с сокетом. В этом случае поток не имеет смысла вообще.

В то время как я не уверен, почему Вы выполнение, что HttpWebRequest легко выполняет к данным чтения-записи к сокету, Вы используете Отправить/Получить методы. Если Вы хотите иметь поток как доступ к сокету TCP, необходимо использовать классы TcpClient/TcpListener, которые переносят сокет и обеспечивают сетевой поток для него.

4
ответ дан 3 December 2019 в 20:44
поделиться

Существует также класс NetworkStream, который берет Сокет в качестве параметра.;)

3
ответ дан 3 December 2019 в 20:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: