androidcsocket
① android socket通信延遲怎麼解決
Handle 吧,
② android socket接收事件為什麼沒有監聽事件,要用死循環呢
Android 的 onClikcListener onTouchEvent 等是Android API(編程文檔介面)
2.設計目的
編程介面全都是根據需求設定的,比如Google事先考慮開發者有使用監聽事件的需求,才預定義了onClickListener onItemListener這些介面,並且將這些底層實現,封裝到了c和C++層,開發者只需要直接使用Google事先為我們准備好的介面即可。
Socket ,首先Socket並不是Google事先設計好的,Socke中文名稱作套接字,你網路搜套接字編程,可以認識到Socket開發是專門的編程技術,而Socket本身又是網路通信協議的基礎設施,Socket的誕生歷史,高於Android,甚至高於Java,Socekt是計算機提供進程通信能力的編程介面,確切的說,它甚至可以提供不同主機間不同進程的通信能力,(包括同一主機里不同進程的通信能力)
主機?端系統?網路協議?運輸層?傳輸層?套接字?埠?
我說的這些專業名詞,也許你一時半會並不能理解
值得慶幸的是,當你了解到這里,你起碼能想明白,為什麼有的人說,Android 程序,也可以做伺服器了,因為Socket 提供了其他端系統訪問Android程序的能力,能被請求訪問的程序,可以稱作服務端。
想深入了解Socket的設計原理、設計本意,需要深厚的計算機網路知識,在這里我建議你閱讀《計算機網路-自頂向下方法》閱讀前三章,也許你對網路編程會有更深的理解。
總結來說:
Android的Listener系列監聽事件,其實只是響應用戶I/O操作而已,是人與硬體設備的通信,安卓系統提供維持監聽事件的能力,所以你能根據某些事件作出響應
Socket的功能,是提供進程通信的能力,安卓系統並不能直接控制Socket的生命周期,它第一層設計是Java代碼,並不是Google自己研發的,第二層、第三層已經直接深入到運輸層協議、計算機系統層原理了,Google為了省事,直接照搬Java API ,無可厚非。
③ android socket怎樣實現斷網重連
由於當網路出現故障時,recv要很長時間才能返回,如果你覺得這種方式不能接受,可以考慮select或者其他模型。
UINT CMonitorDlg::ThreadFunction(LPVOID pParam)
{
WSADATA wsaData;
WSAStartup(...);
while(1)
{
if (WaitSingleObject(hEventKill, 0) == WAIT_OBJECT_0) //
這個hEventKill到主線程里創建,用於控制線程退出
{
break;
}
SOCKET s; //創建套接字
int port=PORT;
int iLen; //從伺服器接收的數據長度
TCHAR recvbuf[BufferLen]; //接受數據的緩沖器
struct sockaddr_in serv1; //伺服器端地址
serv1.sin_family=AF_INET;
//需要連接的伺服器地址信息
serv1.sin_port=htons(port); //需要連接的伺服器地址信息
serv1.sin_addr.s_addr=inet_addr(p->Ip); //將命令行的IP地址轉化為二進製表示的網路位元組順序IP地址
s=socket(AF_INET,SOCK_STREAM,0);
if(s==INVALID_SOCKET)
{
AfxMessageBox("socket()failed");//套接字失敗
return 0;
}
if(connect(s,(struct
sockaddr*)&serv1,sizeof(serv1))==INVALID_SOCKET)
{
int
b=WSAGetLastError();
//連接失敗
}
else
{ //連接成功
p->connectstate=true;
do{
在此循環體中我接收數據並對數據做處理(省略部分代碼)
iLen=recv(s,recvbuf,sizeof(recvbuf),0); //接收套接字中的數據放入recvbuf1緩沖區
if(iLen==0) // server調用了close
{
strtempMsg.Format(_T("局 %s 數據傳送結束"),p->Name);
break;
//return 0;
}
else
if(iLen==SOCKET_ERROR) // 網路錯誤
{
int
err=WSAGetLastError();
if (err==WSAECONNRESET
||err==WSAECONNABORTED)
strtempMsg.Format(_T("%s連接中斷"),p->Name);
p->connectstate=false;
break; //
退出do-while循環准備重連
// return -2; //連接異常中斷
}
......
.....省略代碼
}while//do-while
} //else
closesocket(s); //關閉套接字
} // end of
while(1)
WSACleanup();
return 0;
}
④ Android 之間能否通過 socket 進行通信.
第一個問題:這是可以的,android通過socket訪問本機伺服器PC, ip是10.0.2.2。
第二哥問題:用ServerSocket建立一個對象 ServerSocket serverSocket = new ServerSocket(serverListenPort, connectionMaxLength, InetAddress.getByName(serverIpString));
再加一個監聽Socket incoming = serverSocket.accept();就可以檢測客戶端發過來的連接請求,之後使用流就可以完成他們之間的通信了。
原創手打,thanku
⑤ android socket請求數據怎麼抓包
從網路上面搜索到的資料看,要抓取手機中app的網路包有下面幾種方式:
(1).將tcpmp移植到Android平台,然後在命令行下啟動tcpmp進行抓包。Tcpmp程序實際上可以看作是wireshark的命令行版本,將該程序移植到Android平台直接抓包,這是一種最直接的抓包方式,然後將抓獲的數據包文件,從手機傳到windows系統上用wireshark打開進行分析,這種方式貌似不能用於蘋果手機。
(2).使用fiddler,在windows系統上打開fiddler軟體,該軟體會將我們的電腦變成一個代理,然後在手機上設置wifi網路,將代理指定為開啟fiddler的那台電腦,並且埠設置為fiddler偵聽的8888埠,這時候使用手機訪問的數據,就會通過該代理,在fiddler中就可以看到http的數據包。這種方法我試了半天怎麼都看不到數據包,不知道哪裡出問題了,根據原理,這種方式支持可以通過代理訪問網路的手機。所以從原理上說是支持Android和蘋果手機的。
(3).通過各種方式在pc電腦上建立wifi熱點,然後使用wireshark在pc電腦上監視該wifi熱點,通過手機連接該熱點訪問網路。這樣wireshark會獲取所有流經該熱點的數據包這種方式適用於所有能夠無線訪問的手機,也就是說所有的Android和蘋果手機。
那麼如何在pc電腦上建立wifi熱點呢,有這么幾種辦法:
(1).Win7電腦經過設置,可以將無線網卡設置為wifi熱點,這種方法我以前用過,可以成功,但是步驟繁瑣,而且不一定能夠成功,其他的windows系統估計就沒戲了。
(2).使用軟體自動建立wifi熱點,不需要自己手工配置,這樣的軟體有Connectify Hotspot,獵豹免費wifi,360免費wifi軟體,這幾個軟體我都使用過,比較好用,這種方式同樣也只能針對有無線網卡的筆記本電腦,原理也是將筆記本電腦上的無線網卡建立熱點了,只不過是軟體自動的,不需要人工設置,比方法1要方便。
注意:經過實驗發現,手機連接這種方式建立的熱點,所發送的數據,用wireshark去抓包,需要捕獲電腦上本身聯網的那個「網路連接」,例如我的筆記本上面有一個「本地連接」,該連接是使用有線網路的。我用獵豹免費wifi軟體建立一個熱點之後,我的電腦上多出一個「無線網路連接3」,可以看到該「無線網路連接3」是獵豹生成的,但是我抓包的時候,wireshark需要捕獲「本地連接」上的包,也就是我的手機訪問的數據實際上還是使用的「本地連接」,通信IP也是「本地連接」上的IP地址,而在手機的wifi連接設置中看到的ip地址,在我抓的包中也搜不到,也就是說手機通過該熱點訪問網路,實際上還是使用的「本地連接」的IP地址,至於是什麼原理,我目前也不太清楚。但是下面要說的隨身wifi硬體則與此不同,隨身wifi是建立了網卡。
(3).使用隨身wifi硬體。這種也是很方便的方法,而且比較穩定,對筆記本電腦和台式機都可以使用。我之前買了一個360的隨身wifi(不是打廣告,本人對360公司不感冒,但是他的隨身wifi做的確實還可以,同事中有買小米wifi的,不太穩定)。只要在360的官網上下載驅動,直接插上隨身wifi就可以使用,我推薦使用這種方法。
如果你用的是筆記本電腦可以使用方法2,如果是台式機器可以使用方法3。
⑥ android的socket怎樣判斷斷線
非阻塞模式,如果暫時沒有數據,返回的值也會是<=0的,如果用阻塞模式的話,返回<=0的值是可以認為socket已經無效了。
當使用 select()函數測試一個socket是否可讀時,如果select()函數返回值為1,
且使用recv()函數讀取的數據長度為0 時,就說明該socket已經斷開。
經過代碼試驗,如果進程受到一些信號時,例如:EINTR,recv()返回值小於等於0時,這是就需要判斷 errno是否等於 EINTR , 如果errno == EINTR 則說明recv函數是由於程序接收到信號後返回的,socket連接還是正常的,不應close掉socket連接。
如果write,我覺得還有一些情況需要考慮,那就是寫的太快的時候,有可能buffer寫滿了,這是,errno是EAGAIN,可以根據實際需要,如果errno是EAGAIN的話,再寫幾次。
當然,read的時候也有類似write的情況,需要check一下errno,如果是EAGAIN或者EINTR,最好不要立刻終止操作,再嘗試一下!
這是我寫的一個代碼!int SocketConnected(int sock)
{
int res,recvlen;
char buf[20] = {'\0'};
struct timeval timeout={3,0};
fd_set rdfs;
FD_ZERO(&rdfs);
FD_SET(sock,&rdfs);
res = select(sock+1,&rdfs,NULL,NULL,&timeout);
if(res > 0){
recvlen = recv(sock,buf,sizeof(buf),0);
if(recvlen > 0){
printf("socket connected\n");
return 1;
} else if (recvlen < 0 ){
if(errno == EINTR){
printf("socket connected\n");
return 1;
}else {
printf("socket disconnected! connect again!\n");
return 0;
}
} else if (recvlen == 0){
printf("socket disconnected!connect again\n");
return 0;
}
} else if(res == 0 ){
//time out
printf("socket connected\n");
return 1;
} else if(res < 0){
if (errno == EINTR){
printf("socket connected\n");
return 1;
}else{
printf("socket disconnected ! connect again!\n");
return 0;
}
}
return 0;
}
⑦ android socket 問題。。。。。
輸出到result2
說明「socket.receive(packet);」這句有問題啊,檢查下socket 啊!
我還沒學android的東西,就是靠java知識聯想的,希望對你有幫助。
以前在java中用socket的時候也經常出現類似的錯誤,多調試多測試,加油啊
你可以debug一下試試啊,看看是哪裡的問題
⑧ Android socket通信能發數據但不能接收到數據
我C#項目中做過同樣的Android移動Socket通信。
Android客戶端:
SocketClient對象receive函數就調用讀取函數,當然之前是打開了Socket連接。
publicStringreceive()throwsIOException{
BufferedReaderreader=newBufferedReader(
newInputStreamReader(client.getInputStream()));
Stringtxt=reader.readLine();
returntxt;
}
Activity頁面使用任務不間斷監聽接收。
<Void,Void,Void>{
@Override
protectedVoiddoInBackground(Void...arg0){
SocketClientclient=SocketClient.getInstance();
while(true)
{
try{
Thread.sleep(5000);
Stringre=client.receive();
if(re==null||(re!=null&&re.equals(""))){
continue;
}
if(isCancelled())
returnnull;
//TODO:處理接收到消息
}catch(SocketExceptione){
//服務端斷開,啟動重連任務
if(e.getMessage().contains("ECONNRESET")){
reconnectTask=newReconnectServerTask();
reconnectTask.execute((Void)null);
}
returnnull;
}catch(IOExceptione){
e.printStackTrace();
}catch(InterruptedExceptione){
e.printStackTrace();
}catch(Exceptione){
e.printStackTrace();
}
}
}
}
⑨ android socket 異常退出問題
你沒有用線程!!!
--------------------
客戶Socket
產生Socket對象,客戶端連接服務端的埠,這也需要放到線程中,由newSocket()子程序負責; 讀Socket得到的字元串通過消息傳給主程序協助顯示,這由clientRead(Socket sk)子程序負責,這兩個耗時性子程序都要放到子線程才能工作, clientRead(final String ip,final int port)產生即時子線程供調用。
Socket newSocket(String ip,int port)
{ Socket sk=null;
try
{ sk=new Socket(ip,port); // 連接服務端,返回Socket
}
catch(Exception e)
{
}
return(sk);
}
void clientRead(Socket sk)
{ // 客戶端讀Socket
DataInputStream inf;
try
{ inf=new DataInputStream(sk.getInputStream());
while(sk.isConnected() && !sk.isClosed())
{ String s=inf.readUTF();
if (s.length()>0)
{ Message msg=cHandler.obtainMessage(2,s);
cHandler.sendMessage(msg);
}
}
}
catch(Exception e)
{
}
}
void clientRead(final String ip,final int port)
{ // 子線程中客戶端讀Socket
new Thread(new Runnable()
{ @Override
public void run()
{ Socket sk=newSocket(ip,port);
clientSocket=sk;
if (sk!=null)
clientRead(sk);
}
}).start();
}
一次成功的連接,在服務端與客戶端各自都會產生一個Socket對象,並包含了許多方法與屬性,對象中可以知道對方的IP地址與埠,還有判斷連接狀態的函數,如Socket.isConected()和Socket.isClosed(),但這只能判斷自已的Socket是否已連接與斷開,但無法判斷對方的是否斷開狀態,解決的辦法是服務端向對方發「心跳包」或自行在對話協議中向對方發應答命令,以是否響應超時作為判斷對方是否斷開的依據。
⑩ Android Socket通信開發,求詳細過程,附加註釋,謝謝
服務端往Socket的輸出流裡面寫東西,客戶端就可以通過Socket的輸入流讀取對應的內容。Socket與Socket之間是雙向連通的,所以客戶端也可以往對應的Socket輸出流裡面寫東西,然後服務端對應的Socket的輸入流就可以讀出對應的內容。
Socket類型為流套接字(streamsocket)和數據報套接字(datagramsocket)。
Socket基本實現原理
TCP與UDP
1基於TCP協議的Socket
伺服器端首先聲明一個ServerSocket對象並且指定埠號,然後調用Serversocket的accept()方法接收客戶端的數據。accept()方法在沒有數據進行接收的處於堵塞狀態。(Socketsocket=serversocket.accept()),一旦接收到數據,通過inputstream讀取接收的數據。
客戶端創建一個Socket對象,指定伺服器端的ip地址和埠號(Socketsocket=newSocket("172.168.10.108",8080);),通過inputstream讀取數據,獲取伺服器發出的數據(OutputStreamoutputstream=socket.getOutputStream()),最後將要發送的數據寫入到outputstream即可進行TCP協議的socket數據傳輸。