基于TCP 的 Socket 通信

首先在PC服务端 ipconfig,获取 IPv4地址:1921.68.1.103。端口号随便写,大于 1024 即可。

【注】不能再主线程里 new Socket(),否则可能真机不能运行,模拟机可以。

1、Android 端 Layout 布局文件。

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:paddingBottom="@dimen/activity_vertical_margin"
 6     android:paddingLeft="@dimen/activity_horizontal_margin"
 7     android:paddingRight="@dimen/activity_horizontal_margin"
 8     android:paddingTop="@dimen/activity_vertical_margin"
 9     tools:context=".MainActivity" >
10     
11     <LinearLayout
12         android:layout_width="fill_parent"
13         android:layout_height="wrap_content"
14         android:id="@+id/layout1"
15         android:gravity="bottom"
16         android:orientation="horizontal" >
17 
18         <EditText 
19             android:layout_width="match_parent"
20             android:layout_height="wrap_content"
21             android:maxLines="1"
22             android:layout_weight="1.0"
23             android:id="@+id/txt"
24             />
25         <Button 
26             android:layout_width="wrap_content"
27             android:layout_height="wrap_content"
28             android:id="@+id/send"
29             android:text="发送"
30             />
31     </LinearLayout>
32 
33     <ScrollView
34         android:id="@+id/scrollView1"
35         android:layout_width="fill_parent"
36         android:layout_height="match_parent"
37         android:layout_below="@id/layout1"
38         android:background="#cccccc"
39         android:scrollbars="vertical|none" >
40 
41         <TextView
42             android:id="@+id/content"
43             android:layout_width="fill_parent"
44             android:layout_height="wrap_content" />
45 
46     </ScrollView>
47 </RelativeLayout>
activity_main.xml

2、在 AndroidManifest.xml 中添加网络权限,注意要添加 WIFI 权限,否则可能真机不能运行。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

3、先运行服务端 Java Application 程序。

  1 import java.io.BufferedReader;
  2 import java.io.IOException;
  3 import java.io.InputStreamReader;
  4 import java.io.PrintWriter;
  5 import java.net.ServerSocket;
  6 import java.net.Socket;
  7 import java.util.ArrayList;
  8 import java.util.Iterator;
  9 import java.util.List;
 10 
 11 public class MyServerSocket {
 12     
 13     ServerSocket ss;
 14     // 该集合 保存所有与服务器连接的socket
 15     List<Socket>sockets ;
 16     
 17     public MyServerSocket() {
 18         sockets = new ArrayList<Socket>();
 19         //初始化服务器
 20         init();
 21         
 22     }
 23 
 24     private void init() {
 25 
 26         try {
 27             ss = new ServerSocket(30000);
 28             
 29             while(true){
 30                 
 31                 System.out.println("等待连接……");
 32                 Socket s = ss.accept();
 33                 sockets.add(s);
 34                 //开启线程
 35                 new Thread(new MyThread(s)).start();
 36                 System.out.println("服务器聊天线程开启,当前客户数" + sockets.size());
 37             }
 38         } catch (IOException e) {
 39             // TODO Auto-generated catch block
 40             e.printStackTrace();
 41         }
 42     }
 43 
 44     public static void main(String[] args) {
 45         new MyServerSocket();
 46     }
 47     
 48     // 转发信息
 49     public void tranMsg(String str){
 50         
 51         Iterator<Socket>it = sockets.iterator();
 52         PrintWriter pw = null;
 53         
 54         while(it.hasNext()){
 55             
 56             Socket s = it.next();
 57             try {
 58                 System.out.println("转发消息……给 " + s.getRemoteSocketAddress());
 59                 pw = new PrintWriter(s.getOutputStream());
 60                 pw.println(str);
 61                 pw.flush();
 62             } catch (IOException e) {
 63                 // TODO Auto-generated catch block
 64                 e.printStackTrace();
 65                 sockets.remove(s);
 66             }
 67         }
 68     }
 69     
 70     class MyThread implements Runnable{
 71         
 72         Socket s;
 73         boolean flag = true;
 74         public MyThread(Socket s){
 75             this.s = s;
 76         }
 77         
 78         @Override
 79         public void run() {
 80             if(s == null){
 81                 return;
 82             }
 83             BufferedReader br = null;
 84             try {
 85                  br = new BufferedReader(new InputStreamReader(s.getInputStream()));
 86                  
 87                  while(flag){
 88                     if(s.isClosed()){
 89                         System.out.println("服务器端 socket 关闭");
 90                         flag = false;
 91                         break;
 92                     }
 93                     
 94                     String ls = br.readLine();
 95                     if(ls != null && ls.length() > 1){
 96                         System.out.println("收到信息:"+ls);
 97                         //全部转发
 98                         tranMsg(ls);
 99                     }
100                     Thread.sleep(100);
101                 }
102             } catch (IOException e) {
103                 // TODO Auto-generated catch block
104                 e.printStackTrace();
105             } catch (InterruptedException e) {
106                 // TODO Auto-generated catch block
107                 e.printStackTrace();
108             }finally{
109                 if(br != null){
110                     try {
111                         br.close();
112                     } catch (IOException e) {
113                         // TODO Auto-generated catch block
114                         e.printStackTrace();
115                     }
116                 }
117             }
118         }
119         
120     }
121 }
MyServerSocket.java

4、再启动 Android 端 ClientSocket 程序。

  1 import android.support.v7.app.ActionBarActivity;
  2 import android.os.Bundle;
  3 import android.view.Menu;
  4 import android.view.MenuItem;
  5 
  6 import java.io.BufferedReader;
  7 import java.io.IOException;
  8 import java.io.InputStreamReader;
  9 import java.io.PrintWriter;
 10 import java.net.Socket;
 11 import java.net.UnknownHostException;
 12 
 13 import android.os.Bundle;
 14 import android.os.Handler;
 15 import android.os.Message;
 16 import android.app.Activity;
 17 import android.app.AlertDialog;
 18 import android.app.Dialog;
 19 import android.content.DialogInterface;
 20 import android.util.Log;
 21 import android.view.Menu;
 22 import android.view.View;
 23 import android.view.View.OnClickListener;
 24 import android.widget.Button;
 25 import android.widget.EditText;
 26 import android.widget.TextView;
 27 import android.widget.Toast;
 28 
 29 public class MainActivity extends Activity {
 30     
 31     Button send;
 32     EditText txt;
 33     TextView content;
 34     Socket socket;    // Socket 引用
 35     boolean flag = true;
 36     String strIPAddress;
 37     
 38     // 创建 Handler
 39     Handler handler = new Handler(){
 40         @Override
 41         public void handleMessage(Message msg) {
 42             super.handleMessage(msg);
 43             
 44             Bundle b = msg.getData();
 45             content.append(b.getString("txt") + "\n");
 46         }
 47     };
 48     
 49     @Override
 50     protected void onCreate(Bundle savedInstanceState) {
 51         super.onCreate(savedInstanceState);
 52         
 53         setContentView(R.layout.activity_main);
 54         txt = (EditText) findViewById(R.id.txt);
 55         content = (TextView) findViewById(R.id.content);
 56         send = (Button) findViewById(R.id.send);
 57         send.setOnClickListener(new OnClickListener(){
 58             @Override
 59             public void onClick(View v) {
 60                 sendMsg();
 61             }
 62         });
 63         
 64         // 初始化 socket
 65         new Thread(new Runnable(){
 66 
 67             @Override
 68             public void run() {
 69                 // TODO Auto-generated method stub                
 70                 initSocket();
 71                 //Log.i("Tag", "初始化socket结束, socket状态" + socket.isConnected());
 72             }
 73         }).start();
 74     }
 75     
 76     // 初始化 socket 连接
 77     private void initSocket() {
 78         NetworkUtil networkutil = new NetworkUtil();
 79         if(networkutil.isWiFiConnected(this)) {
 80             strIPAddress = networkutil.getWifiIP(this);
 81             txt.getText().append(strIPAddress);
 82             
 83             try {
 84                 socket = new Socket("192.168.1.103", 30000);
 85                 Log.i("Tag", "Socket创建成功!");
 86             } catch (UnknownHostException e) {
 87                 // TODO Auto-generated catch block
 88                 e.printStackTrace();
 89             } catch (IOException e) {
 90                 // TODO Auto-generated catch block
 91                 e.printStackTrace();
 92             }
 93         }else{
 94             showAlterDialog();
 95         } 
 96                 
 97     }
 98     
 99     public void showAlterDialog(){  
100         Dialog alterDialog = new AlertDialog.Builder(this).  
101                 setTitle("警告").  
102                 setMessage("当前WiFi没有正常连接,请连接后再操作.").  
103                 setIcon(android.R.drawable.ic_dialog_alert).  
104                 setPositiveButton("确定", new DialogInterface.OnClickListener() {  
105   
106                     @Override  
107                     public void onClick(DialogInterface dialog, int which) {  
108                         // TODO Auto-generated method stub  
109                         dialog.dismiss();  
110                     }  
111                 }).  
112                 create();  
113         alterDialog.show();    
114     }
115     
116     // 发送消息
117     public void sendMsg(){
118         
119         String txts = txt.getText().toString();
120         if(txts.length() < 1)    return;
121         if(socket == null)    return;
122         PrintWriter pw = null ;
123         
124         try {
125             pw = new PrintWriter(socket.getOutputStream());
126             pw.println(txts);
127             pw.flush();
128         } catch (IOException e) {
129             // TODO Auto-generated catch block
130             e.printStackTrace();
131         }        
132     }
133 
134     // 创建线程处理 接受服务器信息
135     private void initReceiver() {
136         new Thread(new Runnable(){
137             @Override
138             public void run() {
139                 if(socket == null)return;
140                 try {
141                     BufferedReader br = new BufferedReader(
142                             new InputStreamReader(socket.getInputStream()));
143                     while(flag){
144                         final String str = br.readLine();
145                         if(str != null && str.length()>0){
146                             Log.i("Tag", "收到服务器 消息:" + str);
147                             handler.post(new Runnable(){
148                                 @Override
149                                 public void run() {
150                                     Message m = new Message();
151                                     Bundle b = new Bundle();
152                                     b.putString("txt", str);
153                                     m.setData(b);
154                                     handler.sendMessage(m);
155                                     Log.i("Tag", "handler抛出消息");
156                                 }
157                             });
158                         }
159                         Thread.sleep(100);
160                     }
161                 } catch (IOException e) {
162                     // TODO Auto-generated catch block
163                     e.printStackTrace();
164                 } catch (InterruptedException e) {
165                     // TODO Auto-generated catch block
166                     e.printStackTrace();
167                 }
168             }
169         }).start();
170         Log.i("Tag", "接收线程已启动");
171     }
172             
173     @Override
174     public boolean onCreateOptionsMenu(Menu menu) {
175         // Inflate the menu; this adds items to the action bar if it is present.
176         getMenuInflater().inflate(R.menu.main, menu);
177         return true;
178     }
179     
180     @Override
181     protected void onStart() {
182         super.onStart();
183         
184         if(socket == null){
185             Toast.makeText(this, "网络连接错误,Socket异常!请打开网络连接,重新打开本软件",Toast.LENGTH_LONG).show();
186             return;
187         }
188         // 初始化接听
189         initReceiver();
190         Log.i("Tag", "初始化 接收监听器接收");
191     }
192     
193     @Override
194     protected void onPause() {
195         super.onPause();
196         flag = false;
197     }
198 }
MainActivity.java

WIFI 管理程序

 1 import android.content.Context;  
 2 import android.net.ConnectivityManager;  
 3 import android.net.NetworkInfo;  
 4 import android.net.wifi.WifiInfo;  
 5 import android.net.wifi.WifiManager;  
 6   
 7 public class NetworkUtil {  
 8   
 9     /** 
10      *判断wifi是否连接  
11      * @param context 
12      * @return  
13      */  
14     public static boolean isWiFiConnected(Context context){  
15         
16         ConnectivityManager connectManager = 
17                 (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);  
18         NetworkInfo networkInfo = 
19                 connectManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);  
20         if(networkInfo.isConnected()){  
21             return true;  
22         }  
23         else{  
24             return false;  
25         }    
26     }  
27   
28     /** 
29      * 得到wifi连接的IP地址 
30      * @param context 
31      * @return 
32      */  
33     public static String getWifiIP(Context context){  
34         
35         WifiManager wifiManager = 
36                 (WifiManager)context.getSystemService(Context.WIFI_SERVICE);  
37         WifiInfo wifiInfo = wifiManager.getConnectionInfo();  
38         int ipAddr = wifiInfo.getIpAddress();  
39         String ipStr =  int2string(ipAddr);  
40         return ipStr;  
41     }  
42   
43     /** 
44      * 输入int 得到String类型的ip地址 
45      * @param i 
46      * @return 
47      */  
48     private static String int2string(int i){  
49   
50         return (i & 0xFF)+ "." + ((i >> 8 ) & 0xFF) + "." + ((i >> 16 ) & 0xFF) +"."+((i >> 24 ) & 0xFF );  
51   
52     }  
53 }  
NetworkUtil.java

 

5、PC 端也可以有一个测试 Java Application 程序,非常简单的。

 1 import java.io.IOException;
 2 import java.net.Socket;
 3 import java.net.UnknownHostException;
 4 
 5 public class Testclient {
 6 
 7     /**
 8      * @param args
 9      */
10     public static void main(String[] args) {
11         // TODO Auto-generated method stub
12         try {
13             Socket s = new Socket("192.168.1.103", 6677);
14         } catch (UnknownHostException e) {
15             // TODO Auto-generated catch block
16             e.printStackTrace();
17         } catch (IOException e) {
18             // TODO Auto-generated catch block
19             e.printStackTrace();
20         }
21     }
22 
23 }
Testclient.java

 

posted @ 2015-05-21 21:13  壬子木  阅读(233)  评论(0)    收藏  举报