當前位置:首頁 » 安卓系統 » androidsocks

androidsocks

發布時間: 2022-05-03 23:36:35

㈠ android如何與手機進行通信(Socket連接)

其實跟電腦差不多了,android里調用socket的方法,拿到socket後就可以發送數據並接收數據。

我最近正在做android方面的通信,真的想把完整的代碼都給你,可是沒辦法,公司機密。。

給你我的socket連接類吧。。。

package sean.socket;

///////////把MyType的一些方法替換成Writer的方法
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import sean.Sysout;
import sean.business.BusinessCenter;
import sean.business.LoginManager;
import sean.format.MyType;
import sean.io.Reader;
import sean.transfer.BytesBuffer;
import sean.transfer.DataCenter;

public class SocketThread implements Runnable {

String Server = "";
int Port = 0;
static Socket cs = null;
// Thread ioThread=null;
static boolean bool_SocketThread = false;
static OutputStream output = null;

public SocketThread(String server, int port) {
Server = server;
Port = port;
bool_SocketThread = true;
}

@Override
public void run() {
// TODO Auto-generated method stub
while (bool_SocketThread) {
try {
// if (cs == null) {
DataCenter.setBool_Login(false);// 設置登錄失敗
Sysout.println("正在嘗試連接ClientSocket...", Sysout.TempOutDebug);
cs = new Socket(InetAddress.getByName(Server), Port);
if (cs != null) {
Sysout.println("ClientSocket連接成功!__" + cs,
Sysout.TempOutDebug);
cs.setKeepAlive(true);//讓socket保持活動狀態

InputStream input = cs.getInputStream();
output = cs.getOutputStream();
BusinessCenter.sendLoginData();

BytesBuffer bBuffer = new BytesBuffer();
byte[] Buffer = new byte[1024];
int ReadBytes = input.read(Buffer);
while (ReadBytes != -1) {
Sysout.println("已讀取" + ReadBytes + "個位元組到緩沖區",
Sysout.TempOutDebug);
byte[] b = new byte[ReadBytes];
b = MyType.BytesInsertToBytes(Buffer, b, 0);
Reader r = new Reader(b);
Sysout.println(r.toString() + "____ReadBytes=="
+ ReadBytes, Sysout.TempOutDebug);
bBuffer.InsertToBuffer(Buffer, ReadBytes);
ReadBytes = input.read(Buffer);
}
} else {
Sysout.printException("ClientSocket連接失敗!請確認網路正常且伺服器已開啟。");
}
// }
// 執行到這里說明inputstream.read()已中斷,說明socket已斷開連接
// cs=null;
LoginManager.setLoginValue(-1);// 業務中心登錄注銷,即登錄管理器注銷登錄
DataCenter.setBool_Login(false);// 數據中心登錄注銷
Sysout.printException(cs + "已斷開。");
Thread.sleep(2 * 1000);// 睡眠2秒後繼續循環

// try {
// // 判斷ClientSocket是否已斷開
// cs.sendUrgentData(0);
// } catch (IOException e) {
// // TODO Auto-generated catch block
// Sysout.printException("ClientSocket已斷開,重新連接。"+e);
// cs.close();
// cs = null;
// }
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
Sysout.printException("SocketThread.java====解析伺服器名稱發生異常!" + e);
// e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
Sysout.printException("SocketThread發生IO異常,異常消息:" + e);
try {
if (cs != null) {
Sysout.println("准備關閉" + cs, Sysout.TempOutDebug);
cs.shutdownOutput();
cs.shutdownInput();
cs.close();
cs = null;
output = null;
LoginManager.setLoginValue(-1);// 業務中心登錄注銷,即登錄管理器注銷登錄
DataCenter.setBool_Login(false);// 數據中心登錄注銷
Sysout.println(cs + "已關閉。", Sysout.TempOutDebug);
}
try {
Thread.sleep(5000);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
Sysout.printException("SocketThread.java====線程睡眠異常!!"
+ e2);
// e2.printStackTrace();
}
String ExceptionInfos=e.toString();
if(ExceptionInfos.endsWith("Connection refused")){
stopSocketThread();
}
} catch (IOException e1) {
// TODO Auto-generated catch block
Sysout.printException(cs + "關閉發生異常::" + e1);
// e1.printStackTrace();
try {
Thread.sleep(5000);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
Sysout.printException("SocketThread.java====線程睡眠異常!!"
+ e2);
// e2.printStackTrace();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}// while(bool_SocketThread)
Sysout.println("SocketThread已停止。", Sysout.TempOutDebug);
}

public static Socket getSocket() {
return cs;
}

// public void setBool(boolean bool0) {
// bool_SocketThread = bool0;
// }

public static OutputStream getOutputStream() {
return output;
}

public static void stopSocketThread() {
try {
// 停止SocketThread線程,必須先把循環的標志bool_SocketThread置為false,否則可能繼續循環,重新建立socket連接
bool_SocketThread = false;
// 關閉socket
if (cs != null) {
cs.shutdownOutput();
cs.shutdownInput();
cs.close();
cs = null;
output = null;

Sysout.println("ClientSocket已被強制關閉。");
// LoginManager.setLoginValue(-1);// 業務中心登錄注銷,即登錄管理器注銷登錄
// DataCenter.setBool_Login(false);// 數據中心登錄注銷
// byte[] lock=LoginActivity.getLock();
// synchronized(lock){
// lock.notify();
// }
}
} catch (IOException e) {
// TODO Auto-generated catch block
Sysout.printException("強制關閉" + cs + "發生異常::" + e);
// e.printStackTrace();
}
}

}

必須先在android里啟動一個服務,由服務去啟動這個socket線程,因為如果是UI去啟動的話,頁面會卡住。。。

㈡ android socket接收事件為什麼沒有監聽事件,要用死循環呢

  1. socket是Java API(編程文檔介面),為了直接使用Socekt服務,谷歌直接把Java的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通信協議的封裝和解析

android socket通信協議的封裝和解析,其實是和java一樣的,都是通過http中的相關知識來封裝和解析,主要是通過多次握手,如下代碼:

importjava.io.BufferedReader;
importjava.io.BufferedWriter;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
importjava.io.PrintWriter;
importjava.net.ServerSocket;
importjava.net.Socket;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;


publicclassMain{
privatestaticfinalintPORT=9999;
privateList<Socket>mList=newArrayList<Socket>();
privateServerSocketserver=null;
=null;//threadpool

publicstaticvoidmain(String[]args){
newMain();
}
publicMain(){
try{
server=newServerSocket(PORT);
mExecutorService=Executors.newCachedThreadPool();//createathreadpool
System.out.println("伺服器已啟動...");
Socketclient=null;
while(true){
client=server.accept();
//把客戶端放入客戶端集合中
mList.add(client);
mExecutorService.execute(newService(client));//
}
}catch(Exceptione){
e.printStackTrace();
}
}
{
privateSocketsocket;
privateBufferedReaderin=null;
privateStringmsg="";

publicService(Socketsocket){
this.socket=socket;
try{
in=newBufferedReader(newInputStreamReader(socket.getInputStream()));
//客戶端只要一連到伺服器,便向客戶端發送下面的信息。
msg="伺服器地址:"+this.socket.getInetAddress()+"cometoal:"
+mList.size()+"(伺服器發送)";
this.sendmsg();
}catch(IOExceptione){
e.printStackTrace();
}

}

@Override
publicvoidrun(){
try{
while(true){
if((msg=in.readLine())!=null){
//當客戶端發送的信息為:exit時,關閉連接
if(msg.equals("exit")){
System.out.println("ssssssss");
mList.remove(socket);
in.close();
msg="user:"+socket.getInetAddress()
+"exittotal:"+mList.size();
socket.close();
this.sendmsg();
break;
//接收客戶端發過來的信息msg,然後發送給客戶端。
}else{
msg=socket.getInetAddress()+":"+msg+"(伺服器發送)";
this.sendmsg();
}
}
}
}catch(Exceptione){
e.printStackTrace();
}
}
/**
*循環遍歷客戶端集合,給每個客戶端都發送信息。
*/
publicvoidsendmsg(){
System.out.println(msg);
intnum=mList.size();
for(intindex=0;index<num;index++){
SocketmSocket=mList.get(index);
PrintWriterpout=null;
try{
pout=newPrintWriter(newBufferedWriter(
newOutputStreamWriter(mSocket.getOutputStream())),true);
pout.println(msg);
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
}

㈣ 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有幾種方法

/***第一種:客戶端Socket通過構造方法連接伺服器***/
//客戶端Socket可以通過指定IP地址或域名兩種方式來連接伺服器端,實際最終都是通過IP地址來連接伺服器
//新建一個Socket,指定其IP地址及埠號
Socket socket = new Socket("192.168.0.7",80);
/***Socket 客戶端 一些常用設置***/
//客戶端socket在接收數據時,有兩種超時:1.連接伺服器超時,即連接超時;2.連接伺服器成功後,接收伺服器數據超時,即接收超時
//*設置socket 讀取數據流的超時時間
socket.setSoTimeout(5000);
//發送數據包,默認為false,即客戶端發送數據採用Nagle演算法
//但是對於實時交互性高的程序,建議其改為true,即關閉Nagle演算法,客戶端每發送一次數據,無論數據包大小都會將這些數據發送出去
socket.setTcpNoDelay(true);
//設置客戶端socket關閉時,close()方法起作用時延遲1分鍾關閉,如果1分鍾內盡量將未發送的數據包發送出去
socket.setSoLinger(true, 60);
//設置輸出流的發送緩沖區大小,默認是8KB,即8096位元組
socket.setSendBufferSize(8096);
//設置輸入流的接收緩沖區大小,默認是8KB,即8096位元組
socket.setReceiveBufferSize(8096);
//作用:每隔一段時間檢查伺服器是否處於活動狀態,如果伺服器端長時間沒響應,自動關閉客戶端socket
//防止伺服器端無效時,客戶端長時間處於連接狀態
socket.setKeepAlive(true);
/*** Socket客戶端向伺服器端發送數據 ****/
//客戶端向伺服器端發送數據,獲取客戶端向伺服器端輸出流
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//代表可以立即向伺服器端發送單位元組數據
socket.setOOBInline(true);
//數據不經過輸出緩沖區,立即發送
socket.sendUrgentData(65);//"A"
//向伺服器端寫數據,寫入一個緩沖區
//註:此處字元串最後必須包含「\r\n\r\n」,告訴伺服器HTTP頭已經結束,可以處理數據,否則會造成下面的讀取數據出現阻塞
//在write()方法中可以定義規則,與後台匹配來識別相應的功能,例如登錄Login()方法,可以寫為write("Login|test,123 \r\n\r\n"),供後台識別;
bw.write("Login|test,123 \r\n\r\n");
//發送緩沖區中數據,必須有
bw.flush();

/*** Socket客戶端讀取伺服器端響應數據 ****/
//socket.isConnected代表是否連接成功過
if((socket.isConnected() == true) && (socket.isClosed() == false)){//判斷Socket是否處於連接狀態
//客戶端接收伺服器端的響應,讀取伺服器端向客戶端的輸入流
InputStream is = socket.getInputStream();
//緩沖區
byte[] buffer = new byte[is.available()];
//讀取緩沖區
is.read(buffer);
//轉換為字元串
String responseInfo = new String(buffer);
//日誌中輸出
Log.i("TEST", responseInfo);
} //關閉網路
socket.close();
/***第二種:通過connect方法連接伺服器***/
Socket socket_other = new Socket();
//使用默認的連接超時
socket_other.connect(new InetSocketAddress("192.168.0.7",80));
//連接超時2s
socket_other.connect(new InetSocketAddress("192.168.0.7",80),2000);
//關閉socket
socket_other.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

㈥ 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;
}

熱點內容
2d游戲按鍵精靈腳本教程 發布:2025-05-15 14:10:15 瀏覽:277
伺服器上的郵件如何銷毀 發布:2025-05-15 14:02:49 瀏覽:137
飢荒安卓版如何解除手柄模式 發布:2025-05-15 14:02:05 瀏覽:112
演算法強化班 發布:2025-05-15 14:02:04 瀏覽:345
c語言編譯後圖片 發布:2025-05-15 13:51:57 瀏覽:792
沒有被調用的函數會參與編譯嗎 發布:2025-05-15 13:42:51 瀏覽:260
在計算機中ftp的中文 發布:2025-05-15 13:41:07 瀏覽:1000
國網校招要網簽密碼和賬號干什麼 發布:2025-05-15 13:40:25 瀏覽:179
java分 發布:2025-05-15 13:34:36 瀏覽:846
如何下載卡巴斯基安卓版 發布:2025-05-15 13:34:36 瀏覽:480