TCP 是什么,可能有些人不知道先扫一下盲吧。
TCP:Transmission Control Protocol 传输控制协议。TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议。
相当于一个聊天的小应用程序,只能发送文字。
Server端是一个java project 仅仅有一个类Server 代码如下:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Server {
boolean started=false;
ServerSocket ss=null;
Socket s=null;
DataInputStream dis=null;
List<Client> clients=new ArrayList<Client>();
public void start(){
try {
//ServerSocket一直监听TCP的8888端口,1024以内的端口为系统所用
ss=new ServerSocket(8888);
started=true;
}catch(BindException e){
System.out.println("端口使用中......");
System.out.println("请关掉相关 程序,重新运行服务器");
System.exit(0);
}
catch(IOException e){
e.printStackTrace();
}
try {
while(started){
/ServerSocket一直监听,一旦/有客户端连接上来就增加一个Client,来记录这个连接。
s=ss.accept();
Client c=new Client(s);
new Thread(c).start();
//dis.close();
clients.add(c);
}
} catch (Exception e) {
// TODO Auto-generated catch block
try {
dis.close();
s.close();
}
catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
finally{
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Server().start();
}
class Client implements Runnable{
private Socket s=null;
private DataInputStream dis=null;
private DataOutputStream dos=null;
private boolean bconnected=false;
Client(Socket s){
this.s=s;
try {
dis=new DataInputStream(s.getInputStream());
dos=new DataOutputStream(s.getOutputStream());
bconnected=true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void send(String s){
try {
dos.writeUTF(s);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
while (bconnected) {
String str = dis.readUTF();
//如果有一个客户端发送字符串,服务器就把这个字符串发送给其他客户端(除了它自己之外)
for(int i=0;i<clients.size();i++){
Client c=clients.get(i);
if(c!=this)
c.send(str+"\n");
}
}
} catch (EOFException e2) {
System.out.println("Client closed!");
} catch (Exception e) {
// TODO Auto-generated catch block
try {
dis.close();
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} finally {
try {
if (dis != null)
dis.close();
if(dos!=null)
dos.close();
if (s != null)
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Android 客户端就一个Activity,他的代码如下:
package com.broadvision.chat;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView displayArea;
private EditText sendArea;
private Button sendButton;
Socket s=null;
DataOutputStream dao=null;
DataInputStream dis=null;
private boolean bconnect=false;
public void connect(){
try {
//Socket 的Ip地址应该用PC的局域网的IP,不能用127.0.0.1代替,否则Android客户端不能连接到Server上
s=new Socket("192.168.1.100",8888);
dao=new DataOutputStream(s.getOutputStream());
dis=new DataInputStream(s.getInputStream());
System.out.println("Connected!");
bconnect=true;
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public void disconnect(){
try {
dao.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class Read implements Runnable{
public void run() {
try {
while(bconnect){
final String s=dis.readUTF();
System.out.println("read utf=====" + s);
runOnUiThread(new Runnable() {
@Override
public void run() {
displayArea.append(s);
}
});
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
displayArea = (TextView) findViewById(R.id.display_area);
sendArea = (EditText) findViewById(R.id.send_area);
sendButton = (Button) findViewById(R.id.send_button);
connect();
new Thread(new Read()).start();
//当点解“Send”Button时候,就向服务器发送字符串。
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String str=sendArea.getText().toString().trim();
displayArea.append(str+"\n");
sendArea.setText("");
try {
dao.writeUTF(str);
dao.flush();
//dao.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
}
Activity的layout文件内容如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/display_area"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
/>
<EditText
android:id="@+id/send_area"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Send some message" />
<Button android:id="@+id/send_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Send" />
</LinearLayout>
Android项目中的Manifest xml 中应该增加 <uses-permission android:name="android.permission.INTERNET"/> 权限。
Android 项目安装到模拟器和手机上面,
模拟器的效果图如下:
手机的效果图如下:
希望能对大家有所帮助,谢谢指正其中的错误。