2013-07-09 34 views
0

C#应用程序有一个后台工作线程,它启动一个buttonclick。c#监听器和winsock发送者DLL之间的套接字通信

 private void button1_Click(object sender, EventArgs e) 
     { 
      if (bw.IsBusy != true) 
      { 
       bw.RunWorkerAsync(); 
      } 
     } 

     private void bw_DoWork(object sender, DoWorkEventArgs e) 
     { 
      IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 

      TcpListener serverSocket = new TcpListener(localAddr,7898); 
      int requestCount = 0; 
      TcpClient clientSocket = default(TcpClient); 
      serverSocket.Start(); 

      clientSocket = serverSocket.AcceptTcpClient(); 
      requestCount = 0; 

      while ((true)) 
      { 
       try 
       { 
        requestCount = requestCount + 1; 
        NetworkStream networkStream = clientSocket.GetStream(); 
        byte[] bytesFrom = new byte[10025]; 
        networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize); 
        string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom); 
        dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$")); 
        //Console.WriteLine(" >> Data from client - " + dataFromClient); 
        string serverResponse = "Server response " + Convert.ToString(requestCount); 
        Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse); 
        networkStream.Write(sendBytes, 0, sendBytes.Length); 
        networkStream.Flush(); 
        //Console.WriteLine(" >> " + serverResponse); 
       } 
       catch (Exception ex) 
       { 
        //Console.WriteLine(ex.ToString()); 
       } 
      } 

      clientSocket.Close(); 
      serverSocket.Stop(); 
      Console.WriteLine(" >> exit"); 
      Console.ReadLine(); 

我也有在C++ DLL,C#语言参考,下面的代码

 WSADATA WsaDat; 
    if (WSAStartup(MAKEWORD(2,2), &WsaDat) != 0){ 
    cout<<"WSA FAILED\n"; 
    cin.get(); 
    return 0; 
    } 

    SOCKET Socket; 
    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (Socket == SOCKET_ERROR){ 
    cout<<"Socket Failed to load\n"; 
    cin.get(); 
    return 0; 
    } 

    SOCKADDR_IN server; 

    server.sin_port=htons (7898); 
    server.sin_family = AF_INET; 

    server.sin_addr.s_addr = INADDR_ANY; 

    if (bind(Socket, (SOCKADDR *)(&server), sizeof (server)) == SOCKET_ERROR) 
    { 
    cout<<"BINDING FAILED\n"; 
    cin.get(); 
    return 0; 
    } 


    char buffer[256];  // Declaring a buffer on the stack 

    ZeroMemory(buffer, 256); 
    sprintf(buffer,"--------------------- Processing Side (%s) ----------------------  --- \n", (side ? "A" : "B")); 
    int nret = send(Socket, 

     buffer, 

     strlen(buffer), // Note that this specifies the length of the string; not 

       // the size of the entire buffer 

     0);   // Most often is zero, but see MSDN for other options 

如果我踏入的代码,我发现,调试黄色箭头消失在这条线

clientSocket = serverSocket.AcceptTcpClient(); 

C#GUI出现,虽然按钮仍然可以按下,但它不会再次进入代码。我从互联网上搜索了这些代码片段,因此可能存在我不熟悉的错误。任何人都可以看到我的努力出了什么问题吗?为什么调试在上面的行消失了,并且C#gui出现了?

的感谢!

感谢您的答案。我做了以下,但连接调用失败。这是因为端口号?在C#中它是7898.在C++中它是htons(7898),这是另一个数字。

SOCKADDR_IN server; 

server.sin_port=htons (7898); 
server.sin_family = AF_INET; 

server.sin_addr.s_addr = INADDR_ANY; 

if (bind(Socket, (SOCKADDR *)(&server), sizeof (server)) == SOCKET_ERROR) 
{ 
cout<<"BINDING FAILED\n"; 
cin.get(); 
return 0; 
} 
    //---------------------- 
// Connect to server. 
int iResult = connect(Socket, (SOCKADDR *) & server, sizeof (server)); 
if (iResult == SOCKET_ERROR) { 
    wprintf(L"connect function failed with error: %ld\n", WSAGetLastError()); 
    iResult = closesocket(Socket); 
    if (iResult == SOCKET_ERROR) 
     wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError()); 
    WSACleanup(); 
    return 1; 
} 

在C#

IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 

TcpListener serverSocket = new TcpListener(localAddr,7898); 

我读了htons文档,并认为该端口号是好的,而不是问题。那么它不连接? 再次感谢!

回答

0

TcpListener.AcceptTcpClient是一个阻塞操作,意味着在客户端连接之前不会执行其他代码。所以你不能继续调试,因为这个调用永远不会结束。

由于您将所有工作委托给后台线程,因此GUI具有响应性。

+0

谢谢尼古拉!我相信我的客户端是发送信息的C++ dll。我对吗?如果是,我该如何修改代码才能连接到正在监听的c#服务器? – user2192008

1

在C++客户端调用绑定之后,它必须调用connect。直到成功完成连接,呼叫发送才会生效。

+0

也没有理由将它绑定到0以外的任何端口(即让OS分配一个端口)。事实上,在连接这里之前没有真正的理由来绑定它。 –

+0

谢谢Peter.I删除了绑定部分,但它仍然没有连接。为什么不能连接? – user2192008

0

首先,在发生连接错误后调用WSAGetLastError()来获取实际的错误。这可能会给你一些见解。其次,由于指定了无效的大小,我怀疑你得到了10014错误。如果你传递sizeof(sockaddr)而不是sizeof(服务器),你可能会有更多的运气。