0

C# 应用程序有一个后台工作线程,它在单击按钮时启动。

     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#引用的c++ dll中也有,下面的代码

     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 文档,认为端口号没问题,不是问题。那么为什么不连接呢?再次感谢!

4

3 回答 3

1

在 C++ 客户端调用 bind 之后,它必须调用 connect。在成功建立连接之前,调用 send 将不起作用。

于 2013-07-09T18:31:54.353 回答
0

TcpListener.AcceptTcpClient是一个阻塞操作,意味着在客户端连接之前不会执行其他代码。因此,您无法继续调试,因为该调用永远不会完成。

GUI 是响应式的,因为您将所有工作委托给后台线程。

于 2013-07-09T18:14:08.723 回答
0

首先,在发生连接错误后,调用 WSAGetLastError() 以获取实际错误。这可能会给你一些见解。其次,我怀疑您因为指定的大小无效而收到 10014 错误。如果你通过 sizeof(sockaddr) 而不是 sizeof(server) 你可能会有更多的运气。

于 2015-06-04T01:03:00.303 回答