手机客户端通过Socket向PC服务器发送消息

(1)android客户端代码:


public class MainActivity extends Activity {
    private EditText editText;
    private Button button;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText)findViewById(R.id.editText1);
        button = (Button)findViewById(R.id.button1);


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            Thread thread=new Thread(new SendTask());//开启子线程是因为socket通信操作在Android某个版本后就不允许在主线程中进行了
            thread.start();
            }
        });
    }

class SendTask implements Runnable{
    @Override
    public void run() {
        String str=editText.getText().toString();
        Socket socket=null;
        if(str.equals("")||str==null){
            return;
        }else{
            try{
                Log.d("Tankai","Thread="+Thread.currentThread().getName());
                 socket=new Socket("192.168.0.103",18895);//在此处将10.0.2.2作为电脑的IP地址行不通
                DataOutputStream out=new DataOutputStream(socket.getOutputStream());
                Log.d("Tankai","out="+out.toString()+" socket="+socket.toString());
                out.writeUTF(str);
                out.flush();
                out.close();
            }catch (IOException e){
                Log.d("Tankai","无法获取IP:"+e.getMessage());
            }finally {
                if(null!=socket){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
}

(2)UI布局:



    
    
    

(3)PC服务端代码:

public class Server  {

     
     
     
        //启动服务器  
        public static void main(String[] args){  
            Accept accept=new Accept();
            Thread thread=new Thread(accept);
            thread.start();
        }  

         
}



class Accept implements Runnable{
    @Override
    public void run() {
        // TODO Auto-generated method stub
         
           Socket socket=null;
    try {
        
        ServerSocket serverSocket=new ServerSocket(18895);
       while(true) {
           System.out.println("start.......");
            socket=serverSocket.accept();
           System.out.println("socket="+socket.toString());
           DataInputStream inputStream=new DataInputStream(socket.getInputStream());
           String get=inputStream.readUTF();
           System.out.println("手机-》电脑:"+get);
           inputStream.close();
       }
    }catch (IOException e) {
        // TODO: handle exception
        System.out.println("fatal reason= "+e.getMessage());
    }finally {
        if(socket!=null) {
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }   
    }
}

(4)不要忘记加网络权限


    

(5)结果:

start.......
socket=Socket[addr=/192.168.0.100,port=60320,localport=18895]
手机-》电脑:145
start.......
socket=Socket[addr=/192.168.0.100,port=51000,localport=18895]
手机-》电脑:145258
start.......

分析说明:
(1)同样的一段代码,我用华为手机调试,结果却不能向电脑发送消息。显示错误是timeout,我用oppo手机却发送成功。可能是华为手机对socket进行了某些限制。

(2)每发送一次消息之后,再发送下一次消息,手机端的发送端口是改变了的,客户端的接收端口是写死的,没有改变。感觉这样每发一次消息,发送端口就改变,太浪费了。后面研究研究有没有优化方案。

(3)根据结果说明,每个设备在联网时都有一个ip地址,这个IP地址是会发生变化的。然后一个设备上有很多个端口,可以作为接收消息和发送消息的接口。

可以将一个设备理解为一个有很多大门的建筑物,它的地址就是ip(尽管这个IP是变化的),每一个大门就是一个端口,通过端口可以将物资运输进来或者发送出去。

(4)如果用上面的代码不能发送消息,可能的原因是电脑的防火墙限制了socket,尝试关闭一下。

(5)对socket的操作,要放在子线程下进行,目前Android版本是不支持将socket操作放在主线程下进行的。

你可能感兴趣的:(手机客户端通过Socket向PC服务器发送消息)