Как преобразовать IntPtr/Int для Снабжения сокетом?

Пакет bytes является частью стандартной библиотеки, поэтому маловероятно, что он у вас не будет, если у вас есть инструмент go, доступный для вас.

Но учтите, что bytes.ReplaceAll() был добавлен в Go 1.12 , поэтому, если у вас более старый Go SDK, эта функция будет вам недоступна.

Выполните go version, чтобы узнать. Получить последнюю версию Go с официального сайта: https://golang.org/dl/

5
задан Ivan Prodanov 19 April 2009 в 14:07
поделиться

2 ответа

You can't do it because the Socket class creates and manages its own private socket handle. In theory you could use some evil reflection to jamb your socket handle into a private field of a Socket but that's a total hack and I wouldn't do it.

Given a valid socket handle, you can receive data by calling the Win32 recv function via P/Invoke, like this:

[DllImport("ws2_32.dll")]
extern static int recv([In] IntPtr socketHandle, [In] IntPtr buffer,
  [In] int count, [In] SocketFlags socketFlags);

/// <summary>
/// Receives data from a socket.
/// </summary>
/// <param name="socketHandle">The socket handle.</param>
/// <param name="buffer">The buffer to receive.</param>
/// <param name="offset">The offset within the buffer.</param>
/// <param name="size">The number of bytes to receive.</param>
/// <param name="socketFlags">The socket flags.</param>
/// <exception cref="ArgumentException">If <paramref name="socketHandle"/>
/// is zero.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="buffer"/>
/// is null.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the 
/// <paramref name="offset"/> and <paramref name="size"/> specify a range
/// outside the given buffer.</exception>
public static int Receive(IntPtr socketHandle, byte[] buffer, int offset,
  int size, SocketFlags socketFlags)
{
  if (socketHandle == IntPtr.Zero)
    throw new ArgumentException("socket");
  if (buffer == null)
    throw new ArgumentNullException("buffer");
  if (offset < 0 || offset >= buffer.Length)
    throw new ArgumentOutOfRangeException("offset");
  if (size < 0 || offset + size > buffer.Length)
    throw new ArgumentOutOfRangeException("size");

  unsafe
  {
    fixed (byte* pData = buffer)
    {
      return Recv(socketHandle, new IntPtr(pData + offset),
        size, socketFlags);
    }
  }
}
6
ответ дан 14 December 2019 в 09:00
поделиться

В классе Socket ничего нет для этого - хотя он использует базовый дескриптор, есть нет API для манипулирования им, а свойство дескриптора доступно только для чтения.

Возможно, вам лучше всего просто использовать P / Invoking recv и вызывать его напрямую с помощью дескриптора IntPtr.

Быстрый просмотр кода Rotor выглядит так, как будто вы можете избежать создания Socket, закрывая его дескриптор , а затем устанавливая его поле m_handle равным твой собственный. Но для этого требуется Reflection, и если ваш сокет уже подключен (что звучит так, как будто - поскольку вы только что спросили о вызове recv), вам также придется манипулировать закрытым состоянием Socket - что делает эту идею еще менее приятной и более хрупкий.

1
ответ дан 14 December 2019 в 09:00
поделиться
Другие вопросы по тегам:

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