推薦一個學java或C++的網站http://www.weixueyuan.net/,本來想自己學了總結出來再寫博客,現在沒時間,打字太慢!!!!,又想讓這好東西讓許多人知道。
關於網絡通信:每一台電腦都有自己的ip地址,每台電腦上的網絡應用程序都有自己的通信端口,張三的電腦(ip:192.168.1.110)上有一個網絡應用程序A(通信端口5000),李四的電腦(ip:192.168.1.220)上有一個網絡應用程序B(通信端口8000),張三給李四發消息,首先你要知道李四的ip地址,向指定的ip(李四ip:192.168.1.220)發信息,信息就發到了李四的電腦。再指定一下發送的端口號(通信端口8000),信息就發到了李四電腦的網絡應用程序B上。
TCP--一種網絡通信方式而已。分為服務器(網絡應用程序)和客戶端(網絡應用程序),TCP通信過程,首先打開服務器,監聽自己的網絡通信端口(假設為9000),打開客戶端,設置好要連接的ip地址和服務器的網絡通信端口(9000),這樣服務器一旦監聽到網絡通信端口有連接,二者就建立了連接。這是我寫的TCP客服端的開頭。直接拿過來了
因為是服務器所以在布局文件里放一個button用於啟動服務器;一個button用於發送消息;放一個edittext用於監聽端口;一個edittext用於接收消息;一個edittext用於發送消息(我會把源碼放在最后,前面所顯示的我可能會在上面塗鴉的!!!)
<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.Tcpserver.MainActivity" > <!-- 監聽端口號 --> <TextView android:id="@+id/port_TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="監聽的端口:" /> <!-- 端口號 --> <EditText android:id="@+id/port_EditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="8080" android:layout_below="@id/port_TextView" /> <!-- 發送的消息 --> <TextView android:id="@+id/message_TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="發送的消息" android:layout_below="@id/port_EditText"/> <!-- 發送消息框 --> <EditText android:id="@+id/message_EditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="輸入要發送的消息:" android:layout_below="@id/message_TextView" /> <!-- 啟動按鈕 --> <Button android:id="@+id/start_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="啟動服務" android:layout_below="@id/message_EditText" android:layout_alignParentLeft="true" /> <!-- 發送按鈕 --> <Button android:id="@+id/send_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="發送消息" android:layout_below="@id/message_EditText" android:layout_alignParentRight="true" /> <!-- 接收的消息--> <TextView android:id="@+id/receive_TextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/start_button" android:text="接收的消息:" /> <!-- 接收消息框 --> <EditText android:gravity="top"讓消息每回都從編輯文本框的開頭顯示 android:id="@+id/receive_EditText" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/receive_TextView" /> </RelativeLayout>
看一下java的api文檔
所以呢 ServerSocket serversocket = new ServerSocket(8080);就完成了服務器的監聽,
但是由於不讓在主進程里啟動監聽所以就把它放在一個新的進程里吧。看一看下面代碼
package com.Tcpserver; import java.io.IOException; import java.net.ServerSocket; import android.app.Activity; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; public class MainActivity extends Activity { ServerSocket serverSocket;//創建ServerSocket @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** * 讀一下手機wifi狀態下的ip地址,只有知道它的ip才能連接它嘛 */ Toast.makeText(MainActivity.this, getLocalIpAddress(), Toast.LENGTH_SHORT).show(); /** * 啟動服務器監聽線程 */ ServerSocket_thread serversocket_thread = new ServerSocket_thread(); serversocket_thread.start(); } /** * 服務器監聽線程 */ class ServerSocket_thread extends Thread { public void run()//重寫Thread的run方法 { try { serverSocket = new ServerSocket(8080);//監聽8080端口,這個程序的通信端口就是8080了 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * * 獲取WIFI下ip地址 */ private String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); // 獲取32位整型IP地址 int ipAddress = wifiInfo.getIpAddress(); //返回整型地址轉換成“*.*.*.*”地址 return String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); } }
對了不要忘了加權限,一個wifi權限,一個internet權限,打開wifi和網絡需要權限的
加權限過程
然后看一下
再貼一下代碼吧,別忘了加權限,不然要么沒反應要么顯示xxxxx已停止運行
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.Tcpserver" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
好了我就把現在的下載到手機上
這樣一打開這個軟件便啟動了監聽,按鈕,文本框什么的還沒弄
好現在打開電腦上的網絡調試助手
加點功能,點擊啟動服務器按鈕后才啟動服務,但是端口被我們定死了,,,,可不好玩,我們就設置連接的端口號為文本框中的端口號;
int port =Integer.valueOf(PortText.getText().toString());//獲取端口號
package com.Tcpserver; import java.io.IOException; import java.net.ServerSocket; import android.app.Activity; import android.content.SharedPreferences.Editor; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; 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.Toast; public class MainActivity extends Activity { ServerSocket serverSocket;//創建ServerSocket對象 Button startButton; EditText portEditText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** * 讀一下手機wifi狀態下的ip地址,只有知道它的ip才能連接它嘛 */ Toast.makeText(MainActivity.this, getLocalIpAddress(), Toast.LENGTH_SHORT).show(); startButton = (Button) findViewById(R.id.start_button); portEditText = (EditText) findViewById(R.id.port_EditText); startButton.setOnClickListener(startButtonListener); } /** * 啟動服務按鈕監聽事件 */ private OnClickListener startButtonListener = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub /** * 啟動服務器監聽線程 */ ServerSocket_thread serversocket_thread = new ServerSocket_thread(); serversocket_thread.start(); } }; /** * 服務器監聽線程 */ class ServerSocket_thread extends Thread { public void run()//重寫Thread的run方法 { try { int port =Integer.valueOf(portEditText.getText().toString());//獲取portEditText中的端口號 serverSocket = new ServerSocket(port);//監聽port端口,這個程序的通信端口就是port了 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * * 獲取WIFI下ip地址 */ private String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); // 獲取32位整型IP地址 int ipAddress = wifiInfo.getIpAddress(); //返回整型地址轉換成“*.*.*.*”地址 return String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); } }
接着,接收服務器發來的消息
對了有一點說錯了是在
android 之TCP客戶端編程 上的socket
其實socket這個類可以理解為(只要服務器和客服端建立連接就會建立socket),我們可以通過操作socket類中的方法得到我們想要的東西。感覺解釋的也不咋的,不懂
package com.Tcpserver; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import android.app.Activity; import android.content.SharedPreferences.Editor; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; 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.Toast; public class MainActivity extends Activity { ServerSocket serverSocket;//創建ServerSocket對象 Socket clicksSocket;//連接通道,創建Socket對象 Button startButton; EditText portEditText; EditText receiveEditText; InputStream inputstream;//創建輸入數據流 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** * 讀一下手機wifi狀態下的ip地址,只有知道它的ip才能連接它嘛 */ Toast.makeText(MainActivity.this, getLocalIpAddress(), Toast.LENGTH_SHORT).show(); startButton = (Button) findViewById(R.id.start_button); portEditText = (EditText) findViewById(R.id.port_EditText); receiveEditText = (EditText) findViewById(R.id.receive_EditText); startButton.setOnClickListener(startButtonListener); } /** * 啟動服務按鈕監聽事件 */ private OnClickListener startButtonListener = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub /** * 啟動服務器監聽線程 */ ServerSocket_thread serversocket_thread = new ServerSocket_thread(); serversocket_thread.start(); } }; /** * 服務器監聽線程 */ class ServerSocket_thread extends Thread { public void run()//重寫Thread的run方法 { try { int port =Integer.valueOf(portEditText.getText().toString());//獲取portEditText中的端口號 serverSocket = new ServerSocket(port);//監聽port端口,這個程序的通信端口就是port了 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } while (true) { try { //監聽連接 ,如果無連接就會處於阻塞狀態,一直在這等着 clicksSocket = serverSocket.accept(); inputstream = clicksSocket.getInputStream();//獲取輸入流 //啟動接收線程 Receive_Thread receive_Thread = new Receive_Thread(); receive_Thread.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * * 接收線程 * */ class Receive_Thread extends Thread//繼承Thread { public void run()//重寫run方法 { while (true) { try { final byte[] buf = new byte[1024]; final int len = inputstream.read(buf); runOnUiThread(new Runnable() { public void run() { receiveEditText.setText(new String(buf,0,len)); } }); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * * 獲取WIFI下ip地址 */ private String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); // 獲取32位整型IP地址 int ipAddress = wifiInfo.getIpAddress(); //返回整型地址轉換成“*.*.*.*”地址 return String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); } }
runOnUiThread(new Runnable()
{
public void run()
{
receiveEditText.setText(new String(buf,0,len));
}
});
這個是因為不允許在其它線程里對組件進行操作,但是給了
runOnUiThread(new Runnable() { public void run() { //填寫要操作的程序 } });
這種方法來對組件進行操作
最后一個發送消息
package com.Tcpserver; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import android.app.Activity; import android.content.SharedPreferences.Editor; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; 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.Toast; public class MainActivity extends Activity { ServerSocket serverSocket;//創建ServerSocket對象 Socket clicksSocket;//連接通道,創建Socket對象 Button startButton;//發送按鈕 EditText portEditText;//端口號 EditText receiveEditText;//接收消息框 Button sendButton;//發送按鈕 EditText sendEditText;//發送消息框 InputStream inputstream;//創建輸入數據流 OutputStream outputStream;//創建輸出數據流 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** * 讀一下手機wifi狀態下的ip地址,只有知道它的ip才能連接它嘛 */ Toast.makeText(MainActivity.this, getLocalIpAddress(), Toast.LENGTH_SHORT).show(); startButton = (Button) findViewById(R.id.start_button); portEditText = (EditText) findViewById(R.id.port_EditText); receiveEditText = (EditText) findViewById(R.id.receive_EditText); sendButton = (Button) findViewById(R.id.send_button); sendEditText = (EditText) findViewById(R.id.message_EditText); startButton.setOnClickListener(startButtonListener); sendButton.setOnClickListener(sendButtonListener); } /** * 啟動服務按鈕監聽事件 */ private OnClickListener startButtonListener = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub /** * 啟動服務器監聽線程 */ ServerSocket_thread serversocket_thread = new ServerSocket_thread(); serversocket_thread.start(); } }; /** * 服務器監聽線程 */ class ServerSocket_thread extends Thread { public void run()//重寫Thread的run方法 { try { int port =Integer.valueOf(portEditText.getText().toString());//獲取portEditText中的端口號 serverSocket = new ServerSocket(port);//監聽port端口,這個程序的通信端口就是port了 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } while (true) { try { //監聽連接 ,如果無連接就會處於阻塞狀態,一直在這等着 clicksSocket = serverSocket.accept(); inputstream = clicksSocket.getInputStream();// //啟動接收線程 Receive_Thread receive_Thread = new Receive_Thread(); receive_Thread.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * * 接收線程 * */ class Receive_Thread extends Thread//繼承Thread { public void run()//重寫run方法 { while (true) { try { final byte[] buf = new byte[1024]; final int len = inputstream.read(buf); runOnUiThread(new Runnable() { public void run() { receiveEditText.setText(new String(buf,0,len)); } }); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * 發送消息按鈕事件 */ private OnClickListener sendButtonListener = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try { //獲取輸出流 outputStream = clicksSocket.getOutputStream(); //發送數據 outputStream.write(sendEditText.getText().toString().getBytes()); //outputStream.write("0".getBytes()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; /** * * 獲取WIFI下ip地址 */ private String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); // 獲取32位整型IP地址 int ipAddress = wifiInfo.getIpAddress(); //返回整型地址轉換成“*.*.*.*”地址 return String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); } }
布局源碼
<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.Tcpserver.MainActivity" > <!-- 監聽端口號 --> <TextView android:id="@+id/port_TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="監聽的端口:" /> <!-- 端口號 --> <EditText android:id="@+id/port_EditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="8080" android:layout_below="@id/port_TextView" /> <!-- 發送的消息 --> <TextView android:id="@+id/message_TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="發送的消息" android:layout_below="@id/port_EditText"/> <!-- 發送消息框 --> <EditText android:id="@+id/message_EditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="輸入要發送的消息:" android:layout_below="@id/message_TextView" /> <!-- 啟動按鈕 --> <Button android:id="@+id/start_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="啟動服務" android:layout_below="@id/message_EditText" android:layout_alignParentLeft="true" /> <!-- 發送按鈕 --> <Button android:id="@+id/send_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="發送消息" android:layout_below="@id/message_EditText" android:layout_alignParentRight="true" /> <!-- 接收的消息--> <TextView android:id="@+id/receive_TextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/start_button" android:text="接收的消息:" /> <!-- 接收消息框 --> <EditText android:gravity="top" android:id="@+id/receive_EditText" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/receive_TextView" /> </RelativeLayout>
。java源碼
package com.Tcpserver; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import android.app.Activity; import android.content.SharedPreferences.Editor; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; 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.Toast; public class MainActivity extends Activity { ServerSocket serverSocket;//創建ServerSocket對象 Socket clicksSocket;//連接通道,創建Socket對象 Button startButton;//發送按鈕 EditText portEditText;//端口號 EditText receiveEditText;//接收消息框 Button sendButton;//發送按鈕 EditText sendEditText;//發送消息框 InputStream inputstream;//創建輸入數據流 OutputStream outputStream;//創建輸出數據流 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** * 讀一下手機wifi狀態下的ip地址,只有知道它的ip才能連接它嘛 */ Toast.makeText(MainActivity.this, getLocalIpAddress(), Toast.LENGTH_SHORT).show(); startButton = (Button) findViewById(R.id.start_button); portEditText = (EditText) findViewById(R.id.port_EditText); receiveEditText = (EditText) findViewById(R.id.receive_EditText); sendButton = (Button) findViewById(R.id.send_button); sendEditText = (EditText) findViewById(R.id.message_EditText); startButton.setOnClickListener(startButtonListener); sendButton.setOnClickListener(sendButtonListener); } /** * 啟動服務按鈕監聽事件 */ private OnClickListener startButtonListener = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub /** * 啟動服務器監聽線程 */ ServerSocket_thread serversocket_thread = new ServerSocket_thread(); serversocket_thread.start(); } }; /** * 服務器監聽線程 */ class ServerSocket_thread extends Thread { public void run()//重寫Thread的run方法 { try { int port =Integer.valueOf(portEditText.getText().toString());//獲取portEditText中的端口號 serverSocket = new ServerSocket(port);//監聽port端口,這個程序的通信端口就是port了 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } while (true) { try { //監聽連接 ,如果無連接就會處於阻塞狀態,一直在這等着 clicksSocket = serverSocket.accept(); inputstream = clicksSocket.getInputStream();// //啟動接收線程 Receive_Thread receive_Thread = new Receive_Thread(); receive_Thread.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * * 接收線程 * */ class Receive_Thread extends Thread//繼承Thread { public void run()//重寫run方法 { while (true) { try { final byte[] buf = new byte[1024]; final int len = inputstream.read(buf); runOnUiThread(new Runnable() { public void run() { receiveEditText.setText(new String(buf,0,len)); } }); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * 發送消息按鈕事件 */ private OnClickListener sendButtonListener = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try { //獲取輸出流 outputStream = clicksSocket.getOutputStream(); //發送數據 outputStream.write(sendEditText.getText().toString().getBytes()); //outputStream.write("0".getBytes()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; /** * * 獲取WIFI下ip地址 */ private String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); // 獲取32位整型IP地址 int ipAddress = wifiInfo.getIpAddress(); //返回整型地址轉換成“*.*.*.*”地址 return String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); } }
,,,,,源碼
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.Tcpserver" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
好了,一些提示,或者其它什么的親們自己弄吧。可以看看我的android客服端的,我要吃飯去了