将tcp winsocket连接到c#dot net server

时间:2015-08-11 05:15:28

标签: c# sockets winapi tcp

这是问题所在。我想通过 tcp socket 连接将 win32 api app 连接到c#dot net app。 C#服务器看起来像这样:

public class MyServer
{

    // Incoming data from the client.
    public static string data = null;

    public static void StartListening()
    {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        // Establish the local endpoint for the socket.
        // Dns.GetHostName returns the name of the 
        // host running the application.
        IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

        // Create a TCP/IP socket.
        Socket listener = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp);

        // Bind the socket to the local endpoint and 
        // listen for incoming connections.
        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(10);

            // Start listening for connections.
            while (true)
            {
                Console.WriteLine("Waiting for a connection...");
                // Program is suspended while waiting for an incoming connection.
                Socket handler = listener.Accept();
                data = null;

                // An incoming connection needs to be processed.
                while (true)
                {
                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                    if (data.IndexOf("\n") > -1)
                    {
                        Console.WriteLine("Text received : {0}", data);
                        data=null;
                    }
                }
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();

    }

    public static int Main(String[] args)
    {
        StartListening();
        return 0;
    }
}

这很简单,不完美,但事实证明它可以完成它的工作。 Win32 API 程序如下:

DWORD WINAPI myThread(LPVOID lpParameter) {

    int iResult;
    char recvbuf[DEFAULT_BUFLEN];
    //addrinfo holds host address information
    SOCKADDR_IN clientService;
    SOCKET ConnectSocket = INVALID_SOCKET;
    int recvbuflen = DEFAULT_BUFLEN;

    char *sendbuf = "this is a test";


    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }


    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
    clientService.sin_port = htons(11000);

    iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        ConnectSocket = INVALID_SOCKET;
    }

    // Should really try the next address returned by getaddrinfo
    // if the connect call failed
    // But for this simple example we just free the resources
    // returned by getaddrinfo and print an error message


    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }


    iResult = send(ConnectSocket, sendbuf, (int) strlen(sendbuf), 0);
    if (iResult == SOCKET_ERROR) {
        printf("send failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    // shutdown the connection for sending since no more data will be sent
    // the client can still use the ConnectSocket for receiving data
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

}

简化的主要是:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{

    DWORD myThreadID;

    //thread creation
    myHandle = CreateThread(0, 0, myThread, &myCounter, 0, &myThreadID);

    while(1 > 0)
    {
        //do some stuffs
    }
    return 0;
}

所以基本上我正在尝试连接端口 11000 上的本地主机。首先启动服务器,然后当我调试 win32 api 程序时,在调用connect函数后得到 SOCKET_ERROR

inet_addr是否可能返回错误的IP地址版本(6而不是4)?

感谢。

P.S。问题绝对不在网络中,因为这是与localhost的环回连接,并且正如所提到的那样,服务器被测试为在同一台机器,地址和端口上使用另一个客户端(用c#编写)。

我在调试期间注意到的另一个有趣的事实是clientService.sin_addr.s_addr16777343,但ipAddress.Address的值是2399212554

更新:我刚刚使用提供的winsock server测试了winapi客户端,效果非常好。这意味着问题是c#服务器和winapi客户端之间不兼容。那么问题是什么是不兼容的? IP地址,套接字配置还是别的什么?

0 个答案:

没有答案