Android Socket进程通信——Client与Server之间的通信机制

来源:互联网 发布:ov7670中文数据手册 编辑:程序博客网 时间:2024/06/11 06:48

大笑Socket百度百科:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。

在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务

Android实现Client与server之间的通信

创建安卓项目:

微笑1.Android布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.server.MainActivity" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/editText1"
        android:layout_alignRight="@+id/editText1"
        android:text="TextView" />
    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp"
        android:ems="10" />
    <Button
        android:id="@+id/sendButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/editText1"
        android:layout_marginTop="26dp"
        android:background="#00BFFF"
        android:text="发送消息" />
</RelativeLayout>

害羞2.创建服务器

新建类Server

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

public static void main(String[] args) throws IOException {
System.out.println("=========== server start ===========");
ServerSocket serverSocket = new ServerSocket(8089);//端口号可以自己设定
while (true) {
Socket connection = serverSocket.accept();//定义Socket用来接收来自客户端的信息
System.out.println("+++++++ client connected:" + connection.getRemoteSocketAddress().toString());
DataInputStream input = new DataInputStream(connection.getInputStream());
String clientInputStr = input.readUTF();
 
System.out.println("+++++++ client input: " + clientInputStr);
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeUTF("reply: " + clientInputStr);
 
input.close();
out.close();
connection.close();
}
}
}

吐舌头3.创建客户端

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

//UI线程(旧线程)Handler来根据接收的消息,处理UI更新。Thread线程发出Handler消息,通知更新UI。
public Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//定义mhandler对象
mHandler = new Handler() {  
//更新消息
public void handleMessage(Message msg)  {  
            switch(msg.what)  
           {  
           case 1:  //what:1用于消息识别
            TextView textView1 = (TextView)findViewById(R.id.textView1);
               textView1.setText((String)msg.obj);
                break;         
               default:  
               break;        
            }  
            super.handleMessage(msg);  
        }  
   };
Button sendButton = (Button)findViewById(R.id.sendButton);

sendButton.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
//Log.v("test", "onclick");测试
//新建线程
Thread thread = new Thread(new Runnable()  {

@Override
public void run() {
try {
TextView textView1 = (TextView)findViewById(R.id.textView1);
EditText editText = (EditText)findViewById(R.id.editText1);
//客户端
//1、建立Socket连接
Socket client = new Socket("192.168.68.109",8089);

//2、发送数据
DataOutputStream out = new DataOutputStream(client.getOutputStream()); //发送数据
//Log.v("test", editText.getText().toString());
out.writeUTF(editText.getText().toString());

//3、接收返回信息
DataInputStream in = new DataInputStream(client.getInputStream());//接收完成读取Socket的输入流

Message msg = new Message();
msg.what = 1;//what用作标记符,在switch中要根据what的值来确定对哪一个控件进行操作,当然在这个项目中只有一个TextView可操作
msg.obj = in.readUTF();//将接收到服务器发来的消息存储到msg中去,然后放到mHandler中去处理更新/显示操作

//通知mHandler进行信息更新,使新建线程避免进行更新操作,因此要转给UI线程,避免出现线程卡死
mHandler.sendMessage(msg);

//4、关闭Socket
out.close();
in.close();
client.close();

} catch (IOException e) {
System.out.print(e.getMessage());
e.printStackTrace();
}
}
});
//启动线程
thread.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.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

4.运行结果



为什么在创建客户端时要用到多线程:

Android UI 界面就相当于一个线程,当界面启动时,会有很多相应的操作执行,在这个项目中UI界面主要有三个控件:TextView控件、EditView控件、Button控件,我们在EditView中输入内容,当点击Button按钮时此内容会在TextView中显示出来,若是我们想多次输入内容,一旦上次发送消息发送意外卡死,整个UI就不能再使用;线程的使用则可以避免这个问题的出现。我们每次点击Button时创建一个新的线程来处理当前的操作,但是对TextView的显示操作交给其他线程来执行。

0 0
原创粉丝点击