android002,简易PC-Android发送会话
android002,简易PC-Android发送对话
一、思路:
1、首先需要一个服务器,一个客户端:
PC作为服务器,手机Android作为客户端
2、服务器:接收流后将流输出并加上标识后再以流输出发送给客户端
3、客户端:将编辑框输入的字符串以字节流输出给服务器,再接收服务器的流并显示到另一个编辑框内!
4、大体思路如此!其他细节:
A:虽然setText()中括号里是int型数据,但任然可以在里面写字符串,因为EditText继承了TextView
B:流结束要有标识符
C:组件通过查找对应的ID并转型:
button_sendContent = (Button) this.findViewById(R.id.button_sendContent);//发送按钮 edit_content = (EditText) this.findViewById(R.id.edit_content);// 发送内容的编辑框
D:页面的跳转:
// 用户名个密码都正确后则跳转页面 Intent intent = new Intent(FirstActivity.this, SecondActivity.class); FirstActivity.this.startActivity(intent);
E:之后添加的Activity需要注册:
<activity android:name=".SecondActivity"></activity>
F:使用互联网,需要添加互联网权限:
二、源代码及其注释:
1、服务器PC端:
package androidke.flycatdeng.lesson002; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * 服务器PC * @author flycatdeng * */ public class ChatServer { // 声明 Socket client;// 客户机对象 OutputStream ous;// 输出流对象 InputStream ins;// 输入流对象 /** * 启动服务器方法 */ public void processChat(int port) throws Exception { ServerSocket server = new ServerSocket(port);// 首先创建一个服务器并指定窗口 System.out.println("服务器创建成功,端口:" + port);//打印端口 // 服务器处于阻塞等待状态,但是如果这样就像手机接电话一样 只能一个客户,所以我们要等待循环 while (true) { client = server.accept(); System.out.println("有客户进来哒,IP是:" + client.getRemoteSocketAddress());// 打印客户的IP地址 dealClient(client);// 处理客户 } } // 处理用户的方法 public void dealClient(Socket client) throws Exception { // 从连结对象上得到输入输出流对象 ous = client.getOutputStream();// 这个输出的数据将会给连结对象(客户) ins = client.getInputStream();// 这个是客户机上输入的流 String s = "Hello,welcome to use CC\r\n";// 欢迎词 sendMSg(s);// 发送欢迎语 String inputs = readString(ins);//读取从客户机传来的流并转换为字符串 while (!inputs.equals("bye")) {//如果读取到的不是bye则继续读 System.out.println("读到的客户机说:" + inputs); String s2 = "client send:" + inputs + "\r\n"; System.out.println("正准备给客户机发送:" + s2); sendMSg(s2);//将流发送给客户机 inputs = readString(ins);//继续读客户机传来的流 } // 如果输入的字节是bye s = "welcome to here next time \r\n"; sendMSg(s); client.close();//关闭与客户的连结 } /** * 将要输出的字符串封装在一个方法里,以便调用 * @param s :得到的一个从客户机输入的字符串 */ public void sendMSg(String s) throws IOException { System.out.println("发送了" + s); ous.write(s.getBytes());//将字符串以字节数组读出 ous.flush();//强制完全输出 } /** * 读取输入流(一个一个字节的读),并返回输入的字符串 * @param ins:输入流 * @return:返回输入的字符串 * @throws Exception */ public String readString(InputStream ins) throws Exception { System.out.println("开始读流了!!"); // 创建一个字符串缓冲区 StringBuffer stb = new StringBuffer(); int in = ins.read(); System.out.println("这里执行了吗?"); char c; while (in != 13) {// 当不是回车键的时候 c = (char) in;// 强制将int型in转换为char类型 stb.append(c);// 将字符一个一个的附加 in = ins.read();// 再读 } String inputS = stb.toString().trim();// 将stb转换成字符串并去掉末尾的空格 System.out.println("读完流了!!"); return inputS; } // 主函数 public static void main(String[] args) { ChatServer cs = new ChatServer(); try { cs.processChat(8090); } catch (Exception e) { e.printStackTrace(); } } }
2、客户端Android:
第一个Activity:FirstActivity:
package androidke.flycatdeng.lesson002; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class FirstActivity extends Activity { // 声明 Button button_send; EditText edit_username, edit_password; Socket client; static InputStream ins;// 静态输入流对象 static OutputStream ous;// 静态输出流对象 // 这个Activity重写的onCreate方法相当于主函数 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { client = new Socket("220.168.117.31", 8090);//在显示页面之前创建客户对象 System.out.println("已经创建客户"); ous = client.getOutputStream(); ins = client.getInputStream(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } setContentView(R.layout.main);// 主页面为main.xml // 可视后取得各个组件的id并强制转换为相应的组件类型 button_send = (Button) this.findViewById(R.id.button_send);// 提交按钮 edit_username = (EditText) this.findViewById(R.id.edit_username);// 用户名编辑框 edit_password = (EditText) this.findViewById(R.id.edit_password);// 密码编辑框 // 给按钮添加(设置)监听器 button_send.setOnClickListener(ocl); } // 内部匿名类 OnClickListener ocl = new OnClickListener() {// 这个包引进的时候需要注意,选择的是第二个:android.view.View.OnClickListener; // 重写方法 public void onClick(View v) { // 将编辑框的内容得到并转换为字符串 String username = edit_username.getText().toString(); String password = edit_password.getText().toString(); if ("d".equals(username) && "1".equals(password)) { // 用户名个密码都正确后则跳转页面 Intent intent = new Intent(FirstActivity.this, SecondActivity.class); FirstActivity.this.startActivity(intent); } else { // 如果登录错误则提示 Toast.makeText(FirstActivity.this, "用户名不存在活密码错误!", 3).show();// 副本,内容,停留时间以秒为单位 } } }; }
第二个Activity:SecondActivity:
package androidke.flycatdeng.lesson002; import java.io.InputStream; import java.net.Socket; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class SecondActivity extends Activity{ // 声明 Button button_sendContent; EditText edit_content; TextView TextView_show; String content; Socket client; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second);// 转到第二个页面second.xml // //跳转页面后取得其服务器ip和端口 // serverIP=this.getIntent().getStringExtra("localhost"); // port=this.getIntent().getIntExtra("8090", 8090); //创建客户端 对象 System.out.println("执行到这里!!!!!!!!!!"); try { processChat();//显示服务器发来的消息的方法 } catch (Exception e) { e.printStackTrace(); } button_sendContent = (Button) this.findViewById(R.id.button_sendContent);//发送按钮 edit_content = (EditText) this.findViewById(R.id.edit_content);// 发送内容的编辑框 button_sendContent.setOnClickListener(ocl); } // 内部匿名类 OnClickListener ocl = new OnClickListener() {// 这个包引进的时候需要注意,选择的是第二个:android.view.View.OnClickListener; // 重写方法 public void onClick(View v) { content=edit_content.getText().toString(); System.out.println("客户端文本框输入的内容是:"+content); try { sendMSg(content+"\r\n");//将得到的编辑框内的内容以流输出 edit_content.setText("");//将其内容设置为空 content=edit_content.getText().toString();//再显示 processChat();//显示服务器发来的消息的方法,鼠标每次点击按钮都调用这个显示的方法 } catch (Exception e) { e.printStackTrace(); } } }; //创建客户的方法 public void processChat() throws Exception{ System.out.println("执行到这里了!!!!!!!!!!!!!"); String inputs=readString(FirstActivity.ins);//得到了服务器传来的字符串 System.out.println(inputs);//打印是否得到了服务器传来的字符串 TextView_show = (TextView) this.findViewById(R.id.TextView_show);// 显示内容的编辑框 TextView_show.setText(inputs);//设置上面的文本为得到的流的转换的字符串 TextView_show.getText().toString();//将其转换为字符串,如果没有这一句,文本将不会显示 } /** * 将要输出的字符串封装在一个方法里,以便调用 * @param s :得到的一个从客户机输入的字符串 */ public void sendMSg(String s) throws Exception{ System.out.println("在发送吗?"); FirstActivity.ous.write(s.getBytes()); FirstActivity.ous.flush(); System.out.println("向服务器发送流完成"); } /** * 读取输入流(一个一个字节的读),并返回输入的字符串 * @param ins:输入流 * @return:返回输入的字符串 * @throws Exception */ public String readString(InputStream ins) throws Exception { //创建一个字符串缓冲区 StringBuffer stb=new StringBuffer(); int in=ins.read(); char c; while (in != 13) {// 当不是回车键的时候 c = (char) in;// 强制将int型in转换为char类型 stb.append(c);// 将字符一个一个的附加 in = ins.read();// 再读 } String inputS=stb.toString().trim();//将stb转换成字符串并去掉末尾的空格 return inputS; } }
3、第一个页面:main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- 这下面的前两句是每个组件必要的属性 --> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="欢迎使用手机CC" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="用户名:" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/edit_username" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="密码:" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/edit_password" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="提交" android:id="@+id/button_send" /> </LinearLayout>
4、第二个页面:second.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="登录成功" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/TextView_show" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="false" android:id="@+id/edit_content" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="发送" android:id="@+id/button_sendContent" /> </LinearLayout>
5、效果: