【问题标题】:Send data over TCP from android app从 Android 应用程序通过 TCP 发送数据
【发布时间】:2014-02-26 18:34:34
【问题描述】:

我正在尝试从 Android 应用程序发送数据 客户端类src:

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;

public class CClient    
implements Runnable     
{
    private Socket socket;
    private String ServerIP = "10.0.0.14";


    public void run()
    {
        try 
        {
            socket = new Socket("10.0.0.14", 16606);

        }
        catch(Exception e) 
        {
            System.out.print("Whoops! It didn't work!:");
            System.out.print(e.getLocalizedMessage());
            System.out.print("\n");
        }
    }

    public void Send(String s)
    {
        try
        {
            PrintWriter outToServer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
            outToServer.print(s + "\n");
            outToServer.flush();


        }
        catch (UnknownHostException e) {
            System.out.print(e.toString());
        } catch (IOException e) {
            System.out.print(e.toString());
        }catch (Exception e) {
            System.out.print(e.toString());
        }

    }
}

在活动中使用 CClient 类来创建连接和发送数据。 这是活动代码

import android.os.Bundle;
import android.app.Activity;
import android.view.*;
import android.widget.*;


public class Auth extends Activity {

    private ProgressBar mProgress;
    private TextView mTV;

    private CClient mClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_auth);


        mProgress = (ProgressBar) findViewById(R.id.progressBar1);
        mTV =  (TextView) findViewById(R.id.textView4);

        mClient = new CClient();                
        Thread myThready = new Thread(mClient);
        myThready.start();  

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.auth, menu);
        return true;
    }

    public void proc_Login(View v)
    {

        for (int i=0; i<5; i++)
            mClient.Send("asaadsasdasd");
    }

}

问题:仅从客户端(C# 服务器,没有任何错误)接收到一条消息,并且不会发送下一条消息。

【问题讨论】:

    标签: java android tcp


    【解决方案1】:

    此代码有效。我必须添加一个简单的按钮来触发 proc_Login 调用,我用

    进行了测试
    netcat -l -p 8546
    在我的服务器(debian)上,每次按下按钮时,我都会得到 5 个“asaadsasdasd”。 (我使用了 8546 端口,因为它已经在我的防火墙上打开了)。

    我当然加了

    在 AndroidManifest.xml 文件中。

    也许你的服务器代码在收到一行后关闭了套接字。

    还请注意,您不需要线程,AsyncTask 会更合适,尽管对于示例它可以工作。

    MainActivity.java:

    package com.defranoux.testtcpsend;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    
    public class MainActivity extends Activity {
    
      private CClient mClient;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mClient = new CClient();                
        Thread myThready = new Thread(mClient);
        myThready.start();
    
        Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new OnClickListener() {
    
          @Override
          public void onClick(View arg0) {
            proc_Login(arg0);        
          }
        });    
      }
    
    
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
      }
    
      public void proc_Login(View v)
      {
          for (int i=0; i<5; i++)
              mClient.Send("asaadsasdasd");
      }
    
    }
    

    CClient.java:

    package com.defranoux.testtcpsend;
    
    import java.io.*;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class CClient    
    implements Runnable     
    {
        private Socket socket;
        private String ServerIP = "<my server ip goes here>";
        private static final int ServerPort = 8546;
    
        @Override
        public void run()
        {
            try 
            {
                socket = new Socket(ServerIP, ServerPort);
            }
            catch(Exception e) 
            {
                System.out.print("Whoops! It didn't work!:");
                System.out.print(e.getLocalizedMessage());
                System.out.print("\n");
            }
        }
    
        public void Send(String s)
        {
            try
            {
                PrintWriter outToServer = new PrintWriter(
                    new OutputStreamWriter(
                        socket.getOutputStream()));
                outToServer.print(s + "\n");
                outToServer.flush();
    
    
            }
            catch (UnknownHostException e) {
                System.out.print(e.toString());
            } catch (IOException e) {
                System.out.print(e.toString());
            }catch (Exception e) {
                System.out.print(e.toString());
            }
    
        }
    }
    

    【讨论】:

    • 同样的结果,只发送了一条消息。
    • 奇怪。在客户端,你有什么异常吗?
    • 没有任何例外。只需发送一次。
    • 越来越奇怪了。它来自 C# 服务器的任何更改(我猜它会绑定、侦听、接受,然后在 recv 上循环)。您可以在服务器上运行 wireshark 以查看发生了什么,但这是最后的手段......
    • 服务器正常工作。尝试在 c# 中创建简单的 tcp 客户端,效果很好。
    【解决方案2】:

    您永远不会清理与服务器的连接。刷新流后,您需要关闭这些输出流。

    outToServer.flush();
    outToServer.close();
    

    【讨论】:

    • 你能解释一下为什么你让 CClient 作为一个单独的线程运行,而你在线程中所做的唯一工作就是初始化套接字吗? send方法还在主线程中执行
    • 因为无法从主线程创建连接,只能从新线程创建。
    • 没错,我想说的是,您还应该从新线程而不是从 mai 线程发送数据。理想情况下,发送也应该在单独的线程中运行
    猜你喜欢
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 2021-07-06
    相关资源
    最近更新 更多