Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Распределённые приложения и сеть > импорт сишных функций сокета


Автор: Ataru 10.9.2008, 13:31
Подскажите плиз почему не рабоает этот код?
Код

class Program
{
    public const int AF_INET = 2;
    public const int SOCK_STREAM = 1;
    public const int IPPROTO_TCP = 6;

    static void Main(string[] args)
    {
        WSADATA wsaData;
        int iResult = WSAStartup(/*MAKEWORD(2, 2)*/514, out wsaData);
        IntPtr ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        SOCKADDR_IN tcpServerInfo_ = new SOCKADDR_IN();
        tcpServerInfo_.sin_zero = new byte[8];
        tcpServerInfo_.sin_family = AF_INET;
        tcpServerInfo_.sin_port = htons(2200);
        UInt32 dwServerIpAddress = (UInt32)(10) << (3 * 8);
        dwServerIpAddress += (UInt32)(6) << (2 * 8);
        dwServerIpAddress += (UInt32)(0) << (1 * 8);
        dwServerIpAddress += (UInt32)(3) << (0 * 8);
        tcpServerInfo_.sin_addr.s_addr = htonl(dwServerIpAddress);

        connect(ConnectSocket, ref tcpServerInfo_, 16);

        byte[] PreSendBuffer = new byte[77];
        //заполняем буфер для отправки
        //...

        int bytesSent = send(ConnectSocket, ref PreSendBuffer, 77, 0); //тут все отлично, bytesSent = 77!!!
    
        byte[] recvbuf = new byte[17];
        int bytesRecv = recv(ConnectSocket, ref recvbuf, 17, 0); // а тут виснем

        WSACleanup();
        return;
    }

    [DllImport("ws2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    internal static extern Int32 WSAStartup([In] UInt16 wVersionRequested, out WSADATA lpWSAData);

    [DllImport("wsock32.dll")]
    public static extern IntPtr socket(Int32 af, Int32 s_type, Int32 protocol);

    [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern Int32 WSACleanup();

    [DllImport("wsock32.dll")]
    public static extern UInt16 htons(UInt16 hostshort);

    [DllImport("wsock32.dll")]
    public static extern UInt32 htonl(UInt32 hostshort);

    [DllImport("wsock32.dll")]
    public static extern Int32 connect(IntPtr socket, ref SOCKADDR_IN addr, int addrlen);

    [DllImport("ws2_32.dll")]
    public static extern Int32 send(IntPtr socket, ref byte[] buf, Int32 len, Int32 flags);

    [DllImport("ws2_32.dll")]
    public static extern int recv(IntPtr socket, ref byte[] buffer, UInt32 dwBufferCount, UInt32 Flags);
}

[StructLayout(LayoutKind.Sequential)]
internal struct WSADATA
{
    internal short wVersion;
    internal short wHighVersion;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x101)]
    internal string szDescription;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x81)]
    internal string szSystemStatus;
    internal short iMaxSockets;
    internal short iMaxUdpDg;
    internal int lpVendorInfo;
}

[StructLayout(LayoutKind.Sequential)]
public struct SOCKADDR_IN
{
    public struct in_addr
    {
        public UInt32 s_addr;
    }

    public Int16 sin_family;
    public UInt16 sin_port;
    public in_addr sin_addr;
    public byte[] sin_zero;
}


все нормально коннектится и отправляется, но почему-то не принимается... причем этот же код, написанный на С++ прекрасно работает, т.е. в приборе, от которого я жду ответа, не может быть проблемы, проблема в моей программе...

пробовал изменить вызов recv, но не помогает
Код

unsafe
{
   byte[] recvbuf = new byte[17];
   int bytesRecv;
   fixed (byte* pbuf = recvbuf)
   {
      bytesRecv = recv(ConnectSocket, pbuf, 1, 0);  //все равно виснем
   }
}
[DllImport("wsock32.dll")]
unsafe public static extern int recv(IntPtr socket, byte* buffer, UInt32 dwBufferCount, UInt32 Flags);

Автор: jonie 10.9.2008, 22:17
в c# есть .NET классы для работы с сокетами, зачем извращаться?
кроме того, если это работает на С++, то можно на нем и оставить и либо юзать c++.net , либо сделать обертку на С++ в виде COM или просто dll-ки и вызвать ее уже....

конечно, это оффтоп и никак не поможет решить проблему, так что..

Автор: Ataru 11.9.2008, 13:21
обо всем этом оффтопном я уже думал... если было удобно делать dll или использовать классы сокета из .net я бы не парился с импортом функций...
впрочем исходная проблема уже решена, мне на другом форуме подсказали. как ни странно ошибка была в том, что у функции send не должно быть ref перед вторым параметром. а у меня она видимо что-то не то отправляла, поэтому прибор не отвечал.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)