Java對這個模型的支持有很多種Api.而這里我只想介紹有關Socket的編程接口.對于Java而言已經簡化了Socket的編程接口.首先我們來討論有關提供固定位置的服務方是如何建立的.Java提供了ServerSocket來對其進行支持.事實上當你創(chuàng)建該類的一個實力對象并提供一個端口資源你就建立了一個固定位置可以讓其他計算機來訪問你.
成都創(chuàng)新互聯公司是一家成都網站設計、做網站、成都外貿網站建設公司,提供網頁設計,網站設計,網站制作,建網站,按需制作,網站開發(fā)公司,于2013年創(chuàng)立是互聯行業(yè)建設者,服務者。以提升客戶品牌價值為核心業(yè)務,全程參與項目的網站策劃設計制作,前端開發(fā),后臺程序制作以及后期項目運營并提出專業(yè)建議和思路。
Java代碼
ServerSocket server=new ServerSocket(6789);
這里稍微要注意的是端口的分配必須是唯一的.因為端口是為了唯一標識每臺計算機唯一服務的.另外端口號是從0~65535之間的,前1024個端口已經被Tcp/Ip 作為保留端口,因此你所分配的端口只能是1024個之后的.好了.我們有了固定位置.現在所需要的就是一根連接線了.該連接線由客戶方首先提出要求.因此Java同樣提供了一個Socket對象來對其進行支持.只要客戶方創(chuàng)建一個Socket的實例對象進行支持就可以了.
Java代碼
Socket client=new Socket(InetAddress.getLocalHost(),5678);
客戶機必須知道有關服務器的IP地址.對于著一點Java也提供了一個相關的類InetAddress 該對象的實例必須通過它的靜態(tài)方法來提供.它的靜態(tài)方法主要提供了得到本機IP 和通過名字或IP直接得到InetAddress的方法.
好了.上面的方法基本可以建立一條連線讓兩臺計算機相互交流了.可是數據是如何傳輸的呢?事實上I/O操作總是和網絡編程息息相關的.因為底層的網絡是繼續(xù)數據的.除非遠程調用,處理問題的核心在執(zhí)行上.否則數據的交互還是依賴于IO操作的.所以你也必須導入java.io這個包.java的IO操作也不復雜.它提供了針對于字節(jié)流和Unicode的讀者和寫者,然后也提供了一個緩沖用于數據的讀寫.
Java代碼
BufferedReader in=
new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out=new PrintWriter(server.getOutputStream());
上面兩句就是建立緩沖并把原始的字節(jié)流轉變?yōu)閁nicode可以操作.而原始的字節(jié)流來源于Socket的兩個方法.getInputStream()和getOutputStream()方.分別用來得到輸入和輸出.那么現在有了基本的模型和基本的操作工具.我們可以做一個簡單的Socket例程了.
服務方:
Java代碼
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);
Socket client=server.accept();
BufferedReader in=
new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}
}
這個程序的主要目的在于服務器不斷接收客戶機所寫入的信息只到.客戶機發(fā)送"End"字符串就退出程序.并且服務器也會做出"Receive"為回應.告知客戶機已接收到消息.
客戶機代碼:
Java代碼
import java.net.*;
import java.io.*;
public class Client{
static Socket server;
public static void main(String[] args)throws Exception{
server=new Socket(InetAddress.getLocalHost(),5678);
BufferedReader in=
new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out=new PrintWriter(server.getOutputStream());
BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));
while(true){
String str=wt.readLine();
out.println(str);
out.flush();
if(str.equals("end")){
break;
}
System.out.println(in.readLine());
}
server.close();
}
}
客戶機代碼則是接受客戶鍵盤輸入,并把該信息輸出,然后輸出"End"用來做退出標識.
這個程序只是簡單的兩臺計算機之間的通訊.如果是多個客戶同時訪問一個服務器呢?你可以試著再運行一個客戶端,結果是會拋出異常的.那么多個客戶端如何實現呢?
其實,簡單的分析一下,就可以看出客戶和服務通訊的主要通道就是Socket本身.而服務器通過accept方法就是同意和客戶建立通訊.這樣當客戶建立Socket的同時.服務器也會使用這一根連線來先后通訊.那么既然如此只要我們存在多條連線就可以了.那么我們的程序可以變?yōu)槿缦?
服務器:
Java代碼
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);
while(true){
Socket client=server.accept();
BufferedReader in=
new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}
}
}
這里僅僅只是加了一個外層的While循環(huán).這個循環(huán)的目的就是當一個客戶進來就為它分配一個Socket直到這個客戶完成一次和服務器的交互,這里也就是接受到客戶的"End"消息.那么現在就實現了多客戶之間的交互了.但是.問題又來了.這樣做雖然解決了多客戶,可是是排隊執(zhí)行的.也就是說當一個客戶和服務器完成一次通訊之后下一個客戶才可以進來和服務器交互.無法做到同時服務.那么要如何才能同時達到既能相互之間交流又能同時交流呢?很顯然這是一個并行執(zhí)行的問題了.所以線程是最好的解決方案.
那么下面的問題是如何使用線程.首先要做的事情是創(chuàng)建線程并使得其可以和網絡連線取得聯系.然后由線程來執(zhí)行剛才的操作.要創(chuàng)建線程要么直接繼承Thread要么實現Runnable接口,要建立和Socket的聯系只要傳遞引用就可以了.而要執(zhí)行線程就必須重寫run方法.而run方法所做的事情.就是剛才單線程版本main所做的事情.因此我們的程序變成了這樣:
Java代碼
import java.net.*;
import java.io.*;
public class MultiUser extends Thread{
private Socket client;
public MultiUser(Socket c){
this.client=c;
}
public void run(){
try{
BufferedReader in=
new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
//Mutil User but can't parallel
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}catch(IOException ex){
}finally{
}
}
public static void main(String[] args)throws IOException{
ServerSocket server=new ServerSocket(5678);
while(true){
//transfer location change Single User or Multi User
MultiUser mu=new MultiUser(server.accept());
mu.start();
}
}
}
我的類直接從Thread類繼承了下來.并且通過構造函數傳遞引用和客戶Socket建立了聯系.這樣每個線程就有了.一個通訊管道.同樣我們可以填寫run方法.把之前的操作交給線程來完成.這樣多客戶并行的Socket就建立起來了.
距離無線通信技術,利用“藍牙”技術,能夠有效地簡化掌上電腦、筆記本電腦和移動電話手機等移動通信終端設備之間的通信,也能夠成功地簡化以上這些設備與Internet之間的通信,從而使這些現代通信設備與因特網之間的數據傳輸變得更加迅速高效,為無線通信拓寬道路。說得通俗一點,就是藍牙技術使得現代一些輕易攜帶的移動通信設備和電腦設備,不必借助電纜就能聯網,并且能夠實現無線上因特網,其實際應用范圍還可以拓展到各種家電產品、消費電子產品和汽車等信息家電,組成一個巨大的無線通信網絡。
藍牙”的形成背景是這樣的:1998年5月,愛立信、諾基亞、東芝、IBM和英特爾公司等五家著名廠商,在聯合開展短程無線通信技術的標準化活動時提出了藍牙技術,其宗旨是提供一種短距離、低成本的無線傳輸應用技術。這五家廠商還成立了藍牙特別興趣組,以使藍牙技術能夠成為未來的無線通信標準。芯片霸主Intel公司負責半導體芯片和傳輸軟件的開發(fā),愛立信負責無線射頻和移動電話軟件的開發(fā),IBM和東芝負責筆記本電腦接口規(guī)格的開發(fā)。1999年下半年,著名的業(yè)界巨頭微軟、摩托羅拉、三康、朗訊與藍牙特別小組的五家公司共同發(fā)起成立了藍牙技術推廣組織,從而在全球范圍內掀起了一股“藍牙”熱潮。全球業(yè)界即將開發(fā)一大批藍牙技術的應用產品,使藍牙技術呈現出極其廣闊的市場前景,并預示著21世紀初將迎來波瀾壯闊的全球無線通信浪潮。
2.
內置/外置的區(qū)別:內置指藍牙模塊是已經直接安裝在機身內部,直接可以使用;外置則是指藍牙模塊沒有安裝在機身,需要另外安裝一個。
對手機而言,一般是已內置;對大部分電腦則是需要外置,部分筆記本電腦是內置。
3.
JAVA是由Sun公司推出的一種編程語言,也是一個開放、標準、通用的網絡程序運算平臺,用JAVA編寫的應用程序可以適用于多種不同的終端如筆記本電腦、PDA、手機、尋呼機等等而無需重新編寫.
將JAVA引入手機的意義在于手機用戶可以直接從服務器上安全地及時下載大量以JAVA編寫的應用程序,如游戲、城市指南、地圖等等,并使支持JAVA的手機可以實現在高速無線網絡上的運行,用戶不僅可以隨時快速地獲取互聯網上的豐富信息,更可以充分享受互聯網帶來的先進的互動應用.而對于手機用戶格外具有吸引力的是,如果玩厭了某一個手機游戲,可以輕松地將它刪除并下載新的手機游戲.這種開放式的標準給眾多玩家?guī)頍o窮樂趣.
4.
收費問題:Java游戲一般是下載時候要錢,玩的時候不要,但是有的游戲是聯網游戲,需要算流量費。
你好。
很幸運看到你的問題。
但是又很遺憾到現在還沒有人回答你的問題。也可能你現在已經在別的地方找到了答案,那就得恭喜你啦。
可能是你問的問題有些專業(yè)了,沒人會?;蛘邉e人沒有遇到或者接觸過你的問題,所以幫不了你。建議你去問題的相關論壇去求助,那里的人通常比較多,也比較熱心,可能能快點幫你解決問題。
希望我的回答也能夠幫到你!
祝你好運~!
初涉android的藍牙操作,按照固定MAC地址連接獲取Device時,程序始終是異常終止,查了好多天代碼都沒查出原因。今天改了一下API版本,突然就成功連接了??偨Y之后發(fā)現果然是個坑爹之極的錯誤。
為了這種錯誤拼命查原因浪費大把時間是非常不值得的,但是問題不解決更是揪心。可惜我百度了那么多,都沒有給出確切原因。今天特此mark,希望后來者遇到這個問題的時候能輕松解決。
下面是我的連接過程,中間崩潰原因及解決辦法。
1:用AT指令獲得藍牙串口的MAC地址,地址是簡寫的,按照常理猜測可得標準格式。
2:開一個String adress= "************" //MAC地址, String MY_UUID= "************"http://UUID根據通信而定,網上都有。
3:取得本地Adapter用getDefaultAdapter(); 遠程的則用getRemoteDevice(adress); 之后便可用UUID開socket進行通信。
如果中途各種在getRemoteDevice處崩潰,大家可以查看一下當前的API版本,如果是2.1或以下版本的話,便能確定是API版本問題,只要換成2.2或者以上就都可以正常運行了~ ? 這么坑爹的錯誤的確很為難初學者。 ?唉·········· ?為這種小trick浪費很多時間真是難過。
(另外有個重要地方,別忘了給manifest里面加以下兩個藍牙操作權限哦~)
uses-permission?android:name="android.permission.BLUETOOTH"/uses-permission
uses-permission?android:name="android.permission.BLUETOOTH_ADMIN"/uses-permission
下面附上Android藍牙操作中用固定MAC地址傳輸信息的模板,通用搜索模式日后再補刪模板:
private?BluetoothAdapter?mBluetoothAdapter?=?null;
private?BluetoothSocket?btSocket?=?null;
private?OutputStream?outStream?=?null;
private?InputStream?inStream?=?null;
private?static?final?UUID?MY_UUID?=?UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");??//這條是藍牙串口通用的UUID,不要更改
private?static?String?address?=?"00:12:02:22:06:61";?//?==要連接的藍牙設備MAC地址
/*獲得通信線路過程*/
/*1:獲取本地BlueToothAdapter*/
mBluetoothAdapter?=?BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter?==?null)
{
Toast.makeText(this,?"Bluetooth?is?not?available.",?Toast.LENGTH_LONG).show();
finish();
return;
}
if(!mBluetoothAdapter.isEnabled())
{
Toast.makeText(this,?"Please?enable?your?Bluetooth?and?re-run?this?program.",?Toast.LENGTH_LONG).show();
finish();
return;
}
/*2:獲取遠程BlueToothDevice*/
BluetoothDevice?device?=?mBluetoothAdapter.getRemoteDevice(address);
if(mBluetoothAdapter?==?null)
{
Toast.makeText(this,?"Can't?get?remote?device.",?Toast.LENGTH_LONG).show();
finish();
return;
}
/*3:獲得Socket*/
try?{
btSocket?=?device.createRfcommSocketToServiceRecord(MY_UUID);
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Socket?creation?failed.",?e);
}
/*4:取消discovered節(jié)省資源*/
mBluetoothAdapter.cancelDiscovery();
/*5:連接*/
try?{
btSocket.connect();
Log.e(TAG,?"ON?RESUME:?BT?connection?established,?data?transfer?link?open.");
}?catch?(IOException?e)?{
try?{
btSocket.close();
}?catch?(IOException?e2)?{
Log?.e(TAG,"ON?RESUME:?Unable?to?close?socket?during?connection?failure",?e2);
}
}
/*此時可以通信了,放在任意函數中*/
/*??try?{
outStream?=?btSocket.getOutputStream();
inStream?=?btSocket.getInputStream();?//可在TextView里顯示
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Output?stream?creation?failed.",?e);
}
String?message?=?"1";
byte[]?msgBuffer?=?message.getBytes();
try?{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Exception?during?write.",?e);
}
*/
通用搜索模式代碼模板:
簡潔簡潔方式1 demo
作用: 用VerticalSeekBar控制一個 LED屏幕的亮暗。
直接上碼咯~
package?com.example.seed2;
import?android.app.Activity;
import?android.app.AlertDialog;
import?android.app.Dialog;
import?android.os.Bundle;
import?java.io.IOException;
import?java.io.InputStream;
import?java.io.OutputStream;
import?java.util.UUID;
import?android.bluetooth.BluetoothAdapter;
import?android.bluetooth.BluetoothDevice;
import?android.bluetooth.BluetoothSocket;
import?android.content.DialogInterface;
import?android.util.Log;
import?android.view.KeyEvent;
import?android.widget.Toast;
public?class?MetalSeed?extends?Activity?{
private?static?final?String?TAG?=?"BluetoothTest";
private?BluetoothAdapter?mBluetoothAdapter?=?null;
private?BluetoothSocket?btSocket?=?null;
private?OutputStream?outStream?=?null;
private?InputStream?inStream?=?null;
private?VerticalSeekBar?vskb?=?null;
private?static?final?UUID?MY_UUID?=?UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");??//這條是藍牙串口通用的UUID,不要更改
private?static?String?address?=?"00:12:02:22:06:61";?//?==要連接的藍牙設備MAC地址
/**?Called?when?the?activity?is?first?created.?*/
@Override
public?void?onCreate(Bundle?savedInstanceState)?{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.vskb?=?(VerticalSeekBar)super.findViewById(R.id.mskb);
this.vskb.setOnSeekBarChangeListener(new?OnSeekBarChangeListenerX());
mBluetoothAdapter?=?BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter?==?null)
{
Toast.makeText(this,?"Bluetooth?is?not?available.",?Toast.LENGTH_LONG).show();
finish();
return;
}
if(!mBluetoothAdapter.isEnabled())
{
Toast.makeText(this,?"Please?enable?your?Bluetooth?and?re-run?this?program.",?Toast.LENGTH_LONG).show();
finish();
return;
}
}
private?class?OnSeekBarChangeListenerX?implements?VerticalSeekBar.OnSeekBarChangeListener?{
public?void?onProgressChanged(VerticalSeekBar?seekBar,?int?progress,?boolean?fromUser)?{
//Main.this.clue.setText(seekBar.getProgress());
/*??String?message;
byte?[]?msgBuffer;
try?{
outStream?=?btSocket.getOutputStream();
}?catch?(IOException?e)?{
Log.e(TAG,"ON?RESUME?:?Output?Stream?creation?failed.",?e);
}
message?=Integer.toString(?seekBar.getProgress()?);
msgBuffer?=?message.getBytes();
try{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e?(TAG,?"ON?RESUME?:?Exception?during?write.",?e);
}???????*/
}
public?void?onStartTrackingTouch(VerticalSeekBar?seekBar)?{
String?message;
byte?[]?msgBuffer;
try?{
outStream?=?btSocket.getOutputStream();
}?catch?(IOException?e)?{
Log.e(TAG,"ON?RESUME?:?Output?Stream?creation?failed.",?e);
}
message?=Integer.toString(?seekBar.getProgress()?);
msgBuffer?=?message.getBytes();
try{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e?(TAG,?"ON?RESUME?:?Exception?during?write.",?e);
}
}
public?void?onStopTrackingTouch(VerticalSeekBar?seekBar)?{
String?message;
byte?[]?msgBuffer;
try?{
outStream?=?btSocket.getOutputStream();
}?catch?(IOException?e)?{
Log.e(TAG,"ON?RESUME?:?Output?Stream?creation?failed.",?e);
}
message?=Integer.toString(?seekBar.getProgress()?);
msgBuffer?=?message.getBytes();
try{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e?(TAG,?"ON?RESUME?:?Exception?during?write.",?e);
}
}
}
@Override
public?void?onStart()
{
super.onStart();
}
@Override
public?void?onResume()
{
super.onResume();
BluetoothDevice?device?=?mBluetoothAdapter.getRemoteDevice(address);
try?{
btSocket?=?device.createRfcommSocketToServiceRecord(MY_UUID);
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Socket?creation?failed.",?e);
}
mBluetoothAdapter.cancelDiscovery();
try?{
btSocket.connect();
Log.e(TAG,?"ON?RESUME:?BT?connection?established,?data?transfer?link?open.");
}?catch?(IOException?e)?{
try?{
btSocket.close();
}?catch?(IOException?e2)?{
Log?.e(TAG,"ON?RESUME:?Unable?to?close?socket?during?connection?failure",?e2);
}
}
//?Create?a?data?stream?so?we?can?talk?to?server.
/*??try?{
outStream?=?btSocket.getOutputStream();
inStream?=?btSocket.getInputStream();
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Output?stream?creation?failed.",?e);
}
String?message?=?"read";
byte[]?msgBuffer?=?message.getBytes();
try?{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Exception?during?write.",?e);
}
int?ret??=?-1;
while(?ret?!=?-1)
{
try?{
ret?=?inStream.read();
}?catch?(IOException?e)
{
e.printStackTrace();
}
}
*/
}
@Override