【问题标题】:Server remains hang when sending发送时服务器保持挂起
【发布时间】:2012-01-07 18:09:15
【问题描述】:

我正在编写一个客户端 (Android) - 服务器 (c#) 应用程序。我从这里得到代码: How to make client on Android listen to server on C#? 当我只是将消息从客户端发送到服务器以及从服务器发送到客户端(关闭服务器端的套接字)时,一切工作正常。现在,我想要的是:向服务器发送消息,从服务器接收消息,然后再次向服务器发送消息。服务器在发送消息时挂起。如果我在发送后关闭服务器端的套接字,它会给出一个处理错误,我可以从服务器发送数据。

我的服务器代码是:

/*************************************SERVER*****************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace SERVER2
{
    class Program
    {
        public static void Main()
        {
            try
            {
                IPAddress ipAd = IPAddress.Parse("192.168.2.102");

                TcpListener myList = new TcpListener(ipAd, 18001);

                myList.Start();

                Console.WriteLine("The server is running at port 18001...");
                Console.WriteLine("The local End point is  :" +
                                  myList.LocalEndpoint);
                Console.WriteLine("Waiting for a connection.....");
                 m:
                Socket s = myList.AcceptSocket();
                Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);

                byte[] b = new byte[100];
                int k = s.Receive(b);

                char cc = ' ';
                string test = null;
                Console.WriteLine("Recieved1...");
                for (int i = 0; i < k - 1; i++)
                {
                    cc = Convert.ToChar(b[i]);
                    test += cc.ToString();
                }
                Console.WriteLine("Received characters1: "+test);

                ASCIIEncoding asen = new ASCIIEncoding();
                s.Send(asen.GetBytes("The string was recieved by the server."));
                Console.WriteLine("\nSent Acknowledgement");
                //s.Close(); <-if i enable this, i get a dispose error

                k = s.Receive(b);//i get dispose error here

                cc = ' ';
                test = null;
                Console.WriteLine("Recieved2...");
                for (int i = 0; i < k - 1; i++)
                {
                    cc = Convert.ToChar(b[i]);
                    test += cc.ToString();
                }
                Console.WriteLine("Received characters2: " + test);

                /* clean up */
                goto m;
                s.Close();
                myList.Stop();

            }
            catch (Exception e)
            {
                Console.WriteLine("Error..... " + e.Message);
            }
            Console.ReadLine();
        }

    }
}

我的客户代码是:

/******************************CLIENT*****************************************/
    Socket socket = null;
        try 
        {
            Toast.makeText(context,"IP: "+ip+" port: "+port,10000).show();
            InetAddress serverAddr = InetAddress.getByName(ip); 
            socket = new Socket(serverAddr, port);
        } 
        catch (UnknownHostException e1) 
        {
            Toast.makeText(context,"UnknownHostException ",10000).show();
        } 
        catch (IOException e1) 
        {
            Toast.makeText(context,"IOException ",10000).show();
        }

        String message = "1";

        PrintWriter out = null;
        BufferedReader in = null;

        try { 
            Log.d("TCP", "C: Sending: '" + message + "'"); 

            /*write*/
            out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
            out.println(message);
            out.flush();
            /*read*/
            in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
            String text = "";
            String finalText = "";
            while ((text = in.readLine()) != null) 
            {
                finalText += text;
                }
            Toast.makeText(context, "FinalText: "+finalText, 10000).show();
            Log.d("TCP", "C: Sent.");
            Log.d("TCP", "C: Done."); 
            in.close();        

            /*write*/
            out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
            out.println(message);
            out.flush();
        } catch(Exception e) { 
            Log.e("TCP", "S: Error", e); 
        } finally { 
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        } 

谢谢前辈!!!

【问题讨论】:

    标签: c# java android


    【解决方案1】:

    您收到 dispose 错误的原因是因为 s.close() 关闭了套接字,然后您的下一个 s.Receive() 正在尝试从已关闭的套接字中读取。

    您看到的挂起也可能是由您的 java 代码中的in.close(); 引起的。它可能正在关闭底层套接字。尝试将其注释掉,看看是否能解决您的挂起问题。

    不是 C# 方面的专家,但我已经完成了套接字编程。

    基本上你想要的是 1 + n 个线程。

    一个只接受连接的线程。

    对于Socket s = myList.AcceptSocket(); 返回的每个套接字,您需要一个线程来发送/接收数据并处理来自套接字的消息。您还可以使用两个线程(一个发送,一个接收(这是异步情况))。

    【讨论】:

    • 我试图注释掉 in.close() 部分,但没有运气。该应用程序仍然在发送时挂起。我应该把 Socket s = myList.AcceptSocket(); ?
    【解决方案2】:

    您应该使用 tcp 客户端的流。可以在这里找到一个示例:http://msdn.microsoft.com/de-de/library/system.net.sockets.tcplistener.aspx

    请不要使用 goto。 在goto m; 之后你永远不会到达终点线 用 while 循环包围代码,该循环检查是否发生超时或任何其他检查。

    服务器挂掉的原因是他等待100字节接收。

    【讨论】:

    • 我试着像你说的那样使用流,但是当我发送消息时,它挂在这个部分:stream.Write(msg, 0, msg.Length);并且在客户端没有写出任何内容。如果我添加一个 stream.close() 我在 while 循环中得到一个已处理的错误,但我从服务器得到消息。
    【解决方案3】:

    问题是当客户端收到来自服务器的消息时,在while部分进入了一个无限循环。我像这样修改我的应用程序:

    我的客户部分:

    try 
            {
                Toast.makeText(context,"IP: "+ip+" port: "+port,10000).show();
                InetAddress serverAddr = InetAddress.getByName(ip); 
                socket = new Socket(serverAddr, port);
            } 
            catch (UnknownHostException e1) 
            {
                Toast.makeText(context,"UnknownHostException ",10000).show();
            } 
            catch (IOException e1) 
            {
                Toast.makeText(context,"IOException ",10000).show();
            }
    
            String message = "HELLO FROM CLIENT";
    
            PrintWriter out = null;
            BufferedReader in = null;
    
            try { 
                Log.d("TCP", "C: Sending: '" + message + "'"); 
    
                /*write*/
                OutputStream ostr=socket.getOutputStream();
                OutputStreamWriter outputstr=new OutputStreamWriter(ostr);
                BufferedWriter buffw=new BufferedWriter(outputstr);
                out = new PrintWriter(buffw ,true);
                out.println("HELLO 1 FROM CLIENT");
    
                /*read - i modify to this*/
                InputStreamReader reader=new InputStreamReader(socket.getInputStream());
                char[] bytesreceived=new char[50];
                reader.read(bytesreceived    , 0, 50);
                String text="";
                for (int i=0;i<bytesreceived.length;i++)
                {
                    text+=bytesreceived[i];
                }
                Toast.makeText(context, "Received1: "+text.trim(), 10000).show();
                Log.d("IdealLog","Received1: "+text.trim());
    
                /*write*/
                out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
                out.println("HELLO 2 FROM CLIENT");
    
                /*read*/
                reader=new InputStreamReader(socket.getInputStream());
                bytesreceived=new char[50];
                reader.read(bytesreceived    , 0, 50);
                text="";
                for (int i=0;i<bytesreceived.length;i++)
                {
                    text+=bytesreceived[i];
                }
                Toast.makeText(context, "Received2: "+text.trim(), 10000).show();
                Log.d("IdealLog","Received2: "+text.trim());
    
            } catch(Exception e) { 
                Log.e("TCP", "S: Error", e); 
            } finally { 
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } 
            } 
    

    我的服务器端代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    
    namespace SocketServer
    {
        class Program
        {
            static void Main(string[] args)
            {
                IPEndPoint ip = new IPEndPoint(IPAddress.Any, 18001);
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                socket.Bind(ip);
                socket.Listen(10);
                Console.WriteLine("Waiting for a client...");
                Socket client = socket.Accept();
                IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
                Console.WriteLine("Connected with {0} at port {1}", clientep.Address, clientep.Port);
    
    
    
                string welcome = "HELLO 1 FROM SERVER";
                byte[] data = new byte[200];
                int receiveddata=client.Receive(data);
                Console.WriteLine("Received data from CLIENT1: {0}", System.Text.ASCIIEncoding.ASCII.GetString(data).Trim());
    
    
    
                ASCIIEncoding asen = new ASCIIEncoding();
                byte[] data2 = new byte[200];
                data2 = asen.GetBytes(welcome);
                int sentdata=client.Send(data2, data2.Length, SocketFlags.None);
                Console.WriteLine("Sent data from SERVER: {0}", welcome);
    
    
    
                byte[] data3 = new byte[200];
                Console.WriteLine("Receiving data from CLIENT : {0}", "...");
                client.Receive(data3);
    
    
                Console.WriteLine("Received data from CLIENT2: {0}", System.Text.ASCIIEncoding.ASCII.GetString(data3).Trim());
                byte[] data4 = new byte[200];
                data4 = asen.GetBytes("HELLO 2 FROM SERVER");
                sentdata = client.Send(data4, data4.Length, SocketFlags.None);
    
                client.Close();
                socket.Close();
    
    
                Console.WriteLine("Disconnected from {0}", clientep.Address);
    
    
    
                Console.ReadLine();
            }
        }
    }
    

    现在,一切正常,没有挂起。唯一的问题是,我不知道这是否适用于接收、发送文件。

    【讨论】:

      猜你喜欢
      • 2015-03-08
      • 2023-03-25
      • 2018-01-07
      • 2021-12-24
      • 2023-04-05
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      • 2016-10-18
      相关资源
      最近更新 更多