1、PC伺服器端和android手機客戶端socket通信問題
1. PC伺服器啟用ServerSocket
兩個通信實體在建立虛擬鏈路之前,需要有一方先准備好,主動接受來自其他通信實體的連接請求。
使用ServerSocket對象監聽來自客戶端的Socket連接。
//創建ServerSocket對象
ServerSocket ss = new ServerSocket(30000);
//監聽來自客戶端的請求
while(true){
Socket s = ss.accept();
…
}
如果沒有連接,則將一直處於等待狀態。當接收到連接請求後,獲取消息到輸入流,並保存到文件。
//接收客戶端消息
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String str;
BufferedWriter bw = new BufferedWriter(new FileWriter("D:/ApInfo"+ (i++) +".txt"));
while ((str = in.readLine()) != null) {
System.out.println(str);
bw.write(str);
bw.newLine();
}
2. Android終端使用Socket通信
客戶端使用Socket的構造器連接伺服器,指定伺服器IP和埠號就可以了。
Socket s = new Socket(「192.168.1.100」, 30000);
這樣伺服器端的accept()方法就得到響應,從而向下執行,伺服器端和客戶端就形成了一對互相連接的Socket。再進行通信時就沒有伺服器和客戶端之分了,都是通過輸入輸出流進行通信。
詳細步驟:
採用Handler和TimerTask來定時掃描AP信息並發送給伺服器端。TimerTask規定了到達指定的時間所要進行的任務。
TimerTask task = new TimerTask(){
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
handler傳遞message內容:
Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
// 執行定時器時間到了之後由handler傳遞的任務
break;
}
super.handleMessage(msg);
}
}
接下來掃描AP信息並發送給伺服器端,然後將結果保存。
WifiManager wifiManager=(WifiManager) getSystemService(WIFI_SERVICE);
wifiManager.startScan();
mWifiList = wifiManager.getScanResults();
由WifiManager說明可知,它可以用於處理已配置的網路,當前連接的網路及AP信息的掃描等情況。
向伺服器發送消息:
socket = new Socket("192.168.1.211",30000);
//向伺服器端發送消息
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
out.println(message);
其中message為獲取的AP信息,測試收到的信息格式為:
SSID: ICIS_LAB, BSSID: 1c:af:f7:9a:65:e4, capabilities: [WPA-PSK-TKIP+CCMP], level: -80,frequency: 2437
2、android serversocket 伺服器該怎麼搭建
伺服器端是需要用ServerSocket的:
1創建ServerSocket和Socket
2打開連接到Socket的輸入輸出流
3按照協議進行Socket進行讀寫操作
4關閉輸入輸出流,關閉Socket
3、安卓socket編程的伺服器端的地址是什麼
服務端的地址就是你伺服器運行的電腦的ip地址,伺服器運行在哪個電腦,那內個電腦的ip就是你容伺服器端的地址。
使用socket編程的話創建伺服器端的時候一般都是ServerSocket來創建一個對象,通過new構造函數的時候傳入一個埠號,客戶端連接的時候除了使用伺服器端ip還有這個埠號,創建了對象之類,開啟無限循環,用這個對象調用accept()方法,這就是常說的心跳連接,這個方法會一直阻塞,直到有客戶端連接上。
客戶端連接的時候也需要創建Socket對象,實例化這個對象的時候就需要傳入伺服器端ip和埠號,然後就可以利用這個對象獲取輸入輸出流與伺服器交互。
同樣伺服器端的ServerSocket對象調用accept()方法返回的Socket對象也可以獲取輸入輸出流對象,然後利用這些流與客戶端交互。
4、手機作為客戶端,電腦作為伺服器進行android socket通信
1.PC伺服器啟用ServerSocket兩個通信實體在建立虛擬鏈路之前,需要有一方先准備好,主動接受來自其他通信實體的連接請求。使用ServerSocket對象監聽來自客戶端的Socket連接。//創建ServerSocket對象ServerSocketss=newServerSocket(30000);//監聽來自客戶端的請求while(true){Sockets=ss.accept();…}如果沒有連接,則將一直處於等待狀態。當接收到連接請求後,獲取消息到輸入流,並保存到文件。//接收客戶端消息BufferedReaderin=newBufferedReader(newInputStreamReader(client.getInputStream()));Stringstr;BufferedWriterbw=newBufferedWriter(newFileWriter("D:/ApInfo"+(i++)+".txt"));while((str=in.readLine())!=null){System.out.println(str);bw.write(str);bw.newLine();}2.Android終端使用Socket通信客戶端使用Socket的構造器連接伺服器,指定伺服器IP和埠號就可以了。Sockets=newSocket(「192.168.1.100」,30000);這樣伺服器端的accept()方法就得到響應,從而向下執行,伺服器端和客戶端就形成了一對互相連接的Socket。再進行通信時就沒有伺服器和客戶端之分了,都是通過輸入輸出流進行通信。詳細步驟:採用Handler和TimerTask來定時掃描AP信息並發送給伺服器端。TimerTask規定了到達指定的時間所要進行的任務。TimerTasktask=newTimerTask(){publicvoidrun(){Messagemessage=newMessage();message.what=1;handler.sendMessage(message);}};handler傳遞message內容:Handlerhandler=newHandler(){publicvoidhandleMessage(Messagemsg){switch(msg.what){case1://執行定時器時間到了之後由handler傳遞的任務break;}super.handleMessage(msg);}}接下來掃描AP信息並發送給伺服器端,然後將結果保存。WifiManagerwifiManager=(WifiManager)getSystemService(WIFI_SERVICE);wifiManager.startScan();mWifiList=wifiManager.getScanResults();由WifiManager說明可知,它可以用於處理已配置的網路,當前連接的網路及AP信息的掃描等情況。向伺服器發送消息:socket=newSocket("192.168.1.211",30000);//向伺服器端發送消息PrintWriterout=newPrintWriter(newBufferedWriter(newOutputStreamWriter(socket.getOutputStream())),true);out.println(message);其中message為獲取的AP信息,測試收到的信息格式為:SSID:ICIS_LAB,BSSID:1c:af:f7:9a:65:e4,capabilities:[WPA-PSK-TKIP+CCMP],level:-80,frequency:2437
5、自己寫了一個Android的APP,想用socket連接伺服器,伺服器用什麼寫?需要用什麼軟體嗎?
不是很復雜。具體思路:
1.在伺服器端寫一個程序,這程序進行讀取資料庫中你想要的數據,然後再通過socket服務端發送給客戶端。
2.寫個socket客戶端 。
android的不知道是不是這樣!
6、android做客戶端socket如何讓點擊按鈕向伺服器發送信息
使用基於TCP協議的Socket
一個客戶端要發起一次通信,首先必須知道運行伺服器端的主機IP地址。然後由網路基礎設施利用目標地址,將客戶端發送的信息傳遞到正確的主機上,在Java中,地址可以由一個字元串來定義,這個字元串可以使數字型的地址(比如192.168.1.1),也可以是主機名(example.com)。
而在android 4.0 之後系統以後就禁止在主線程中進行網路訪問了,原因是:
主線程是負責UI的響應,如果在主線程進行網路訪問,超過5秒的話就會引發強制關閉,所以這種耗時的操作不能放在主線程里。放在子線程里,而子線程里是不能對主線程的UI進行改變的,因此就引出了Handler,主線程里定義Handler,子線程里使用。
以下是一個android socket客戶端的例子:
---------------------------------Java代碼---------------------------------------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class TCPSocketActivity extends Activity {
public static final String TAG = TCPSocketActivity.class.getSimpleName();
/* 伺服器地址 */
private String host_ip = null;
/* 伺服器埠 */
private int host_port = 0;
private Button btnConnect;
private Button btnSend;
private EditText editSend;
private EditText hostIP;
private EditText hostPort;
private Socket socket;
private PrintStream output;
private String buffer = "";
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_socket_test);
context = this;
initView();
btnConnect.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
host_ip = hostIP.getText().toString();
host_port = Integer.parseInt(hostPort.getText().toString());
new Thread(new ConnectThread()).start();
}
});
btnSend.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new SendThread(editSend.getText().toString())).start();
}
});
}
private void toastText(String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
public void handleException(Exception e, String prefix) {
e.printStackTrace();
toastText(prefix + e.toString());
}
public void initView() {
btnConnect = (Button) findViewById(R.id.btnConnect);
btnSend = (Button) findViewById(R.id.btnSend);
editSend = (EditText) findViewById(R.id.sendMsg);
hostIP = (EditText) findViewById(R.id.hostIP);
hostPort = (EditText) findViewById(R.id.hostPort);
}
private void closeSocket() {
try {
output.close();
socket.close();
} catch (IOException e) {
handleException(e, "close exception: ");
}
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (0x123 == msg.what) {
toastText("連接成功!");
}
}
};
/* 連接socket線程 */
public class ConnectThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
Message msg = Message.obtain();
try {
if (null == socket || socket.isClosed()) {
socket = new Socket();
socket.connect(new InetSocketAddress(host_ip,host_port),5000);
output = new PrintStream(socket.getOutputStream(), true,
"utf-8");
}
msg.what = 0x123;
handler.sendMessage(msg);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*發送信息線程*/
public class SendThread implements Runnable {
String msg;
public SendThread(String msg) {
super();
this.msg = msg;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
output.print(msg);
} catch (Exception e) {
e.printStackTrace();
}
closeSocket();
}
}
public class SocketThread implements Runnable {
public String txt1;
public SocketThread(String txt1) {
super();
this.txt1 = txt1;
}
@Override
public void run() {
// TODO Auto-generated method stub
Message msg = Message.obtain();
try {
/* 連接伺服器 並設置連接超時為5秒 */
if (socket.isClosed() || null == socket) {
socket = new Socket();
socket.connect(new InetSocketAddress(host_ip,host_port),5000);
}
// 獲取輸入輸出流
PrintStream ou = new PrintStream(socket.getOutputStream(),
true, "UTF-8");
BufferedReader bff = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// 讀取發來伺服器信息
String line = null;
buffer = "";
while ((line = bff.readLine()) != null) {
buffer = line + buffer;
}
// 向伺服器發送信息
ou.print(txt1);
ou.flush();
// 關閉各種輸入輸出流
bff.close();
ou.close();
socket.close();
msg.what = 0x123;
handler.sendMessage(msg);
} catch (UnknownHostException e) {
} catch (IOException e) {
}
}
}
}
-----------------------------布局文件activity_socket_test.xml--------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/white"
android:orientation="vertical" >
<EditText
android:id="@+id/hostIP"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:hint="伺服器ip"
android:singleLine="true"
android:inputType="text" />
<EditText
android:id="@+id/hostPort"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:hint="埠"
android:singleLine="true"
android:inputType="number" />
<Button
android:id="@+id/btnConnect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:background="@drawable/style_btn_shape"
android:layout_margin="5dip"
android:text="@string/connect"
android:textColor="@color/white" />
<EditText
android:id="@+id/sendMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:hint="需要發送的內容"
android:inputType="text" />
<Button
android:id="@+id/btnSend"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:background="@drawable/style_btn_shape"
android:layout_gravity="center_vertical|center_horizontal"
android:text="@string/send"
android:textColor="@color/white" />
</LinearLayout>
-------------------------樣式文件style_btn_shape.xml----------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充的顏色 -->
<solid android:color="#0465b2" />
<!-- 設置按鈕的四個角為弧形 -->
<!-- android:radius 弧形的半徑 -->
<corners android:radius="15dip" />
<!-- padding:Button裡面的文字與Button邊界的間隔 -->
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"
/>
</shape>
------------------------------END---------------------------------------
7、建立一個android service伺服器需要什麼,用socket的
1,tomcat
2,Android與伺服器的通信方式主要有兩種,一是Http通信,一是Socket通信。兩者的最大差異在回於,http連接使用答的是「請求—響應方式」,即在請求時建立連接通道,當客戶端向伺服器發送請求後,伺服器端才能向客戶端返回數據。而Socket通信則是在雙方建立起連接後就可以直接進行數據的傳輸,在連接時可實現信息的主動推送,而不需要每次由客戶端想伺服器發送請求
8、自己寫了一個Android的APP,想用socket連接伺服器
最近我在在寫一個APP,用到了socket,在自己電腦上搭建的伺服器,具體過程: 用eclipse寫Java代碼,創建一個serversocket,用來監聽客戶端的請求; 客戶端在發送數據前,首先創建一個Socket,然後直接請求伺服器即可。自己寫了一個Android的APP,想用socket連接伺服器
9、Android伺服器通信的幾種方式詳解
大 學學習網路基礎的時候老師講過,網路由下往上分為物理層、數據鏈路層、網路層、傳輸層、會話層、表示層和應用層。通過初步的了解,我知道IP協議對應於網 絡層,TCP協議對應於傳輸層,而HTTP協議對應於應用層,三者從本質上來說沒有可比性,socket則是對TCP/IP協議的封裝和應用(程序員層面 上)。也可以說,TPC/IP協議是傳輸層協議,主要解決數據如何在網路中傳輸,而HTTP是應用層協議,主要解決如何包裝數據。關於TCP/IP和 HTTP協議的關系,網路有一段比較容易理解的介紹: 「我們在傳輸數據時,可以只使用(傳輸層)TCP/IP協議,但是那樣的話,如果沒有應用層,便無法識別數據內容,如果想要使傳輸的數據有意義,則必須使 用到應用層協議,應用層協議有很多,比如HTTP、FTP、TELNET等,也可以自己定義應用層協議。WEB使用HTTP協議作應用層協議,以封裝 HTTP文本信息,然後使用TCP/IP做傳輸層協議將它發到網路上。」
而我們平時說的最多的socket是什麼呢,實際上socket是對TCP/IP協議的封裝,Socket本身並不是協議,而是一個調用介面(API), 通過Socket,我們才能使用TCP/IP協議。實際上,Socket跟TCP/IP協議沒有必然的聯系。Socket編程介面在設計的時候,就希望也 能適應其他的網路協議。所以說,Socket的出現只是使得程序員更方便地使用TCP/IP協議棧而已,是對TCP/IP協議的抽象,從而形成了我們知道 的一些最基本的函數介面,比如create、listen、connect、accept、send、read和write等等。網路有一段關於 socket和TCP/IP協議關系的說法比較容易理解:「TCP/IP只是一個協議棧,就像操作系統的運行機制一樣,必須要具體實現,同時還要提供對外 的操作介面。這個就像操作系統會提供標準的編程介面,比如win32編程介面一樣,TCP/IP也要提供可供程序員做網路開發所用的介面,這就是 Socket編程介面。」
關於TCP/IP協議的相關只是,用博大精深來講我想也不為過,單單查一下網上關於此類只是的資料和書籍文獻的數量就知道,這個我打算會買一些經典的書籍 (比如《TCP/IP詳解:卷一、卷二、卷三》)進行學習,今天就先總結一些基於基於TCP/IP協議的應用和編程介面的知識,也就是剛才說了很多的 HTTP和Socket。
CSDN上有個比較形象的描述:HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網路通信的能力。
實際上,傳輸層的TCP是基於網路層的IP協議的,而應用層的HTTP協議又是基於傳輸層的TCP協議的,而Socket本身不算是協議,就像上面所說,它只是提供了一個針對TCP或者UDP編程的介面。
下面是一些經常在筆試或者面試中碰到的重要的概念,特在此做摘抄和總結。
一。什麼是TCP連接的三次握手
第一次握手:客戶端發送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。
握手過程中傳送的包里不包含數據,三次握手完畢後,客戶端與伺服器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉 連接之前,TCP 連接都將被一直保持下去。斷開連接時伺服器和客戶端均可以主動發起斷開TCP連接的請求,斷開過程需要經過「四次握手」(過程就不細寫了,就是伺服器和客 戶端交互,最終確定斷開)
二。利用Socket建立網路連接的步驟
建立Socket連接至少需要一對套接字,其中一個運行於客戶端,稱為ClientSocket ,另一個運行於伺服器端,稱為ServerSocket 。
套接字之間的連接過程分為三個步驟:伺服器監聽,客戶端請求,連接確認。
1。伺服器監聽:伺服器端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網路狀態,等待客戶端的連接請求。
2。客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是伺服器端的套接字。為此,客戶端的套接字必須首先描述它要連接的伺服器的套接字,指出伺服器端套接字的地址和埠號,然後就向伺服器端套接字提出連接請求。
3。 連接確認:當伺服器端套接字監聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把伺服器端套接字的描述發給客戶 端,一旦客戶端確認了此描述,雙方就正式建立連接。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求。
三。HTTP鏈接的特點
HTTP協議即超文本傳送協議(Hypertext Transfer Protocol ),是Web聯網的基礎,也是手機聯網常用的協議之一,HTTP協議是建立在TCP協議之上的一種應用。
HTTP連接最顯著的特點是客戶端發送的每次請求都需要伺服器回送響應,在請求結束後,會主動釋放連接。從建立連接到關閉連接的過程稱為「一次連接」。
四。TCP和UDP的區別(考得最多。。快被考爛了我覺得- -\\)
1。 TCP是面向鏈接的,雖然說網路的不安全不穩定特性決定了多少次握手都不能保證連接的可靠性,但TCP的三次握手在最低限度上(實際上也很大程度上保證 了)保證了連接的可靠性;而UDP不是面向連接的,UDP傳送數據前並不與對方建立連接,對接收到的數據也不發送確認信號,發送端不知道數據是否會正確接 收,當然也不用重發,所以說UDP是無連接的、不可靠的一種數據傳輸協議。
2。也正由於1所說的特點,使得UDP的開銷更小數據傳輸速率更高,因為不必進行收發數據的確認,所以UDP的實時性更好。
知 道了TCP和UDP的區別,就不難理解為何採用TCP傳輸協議的MSN比採用UDP的QQ傳輸文件慢了,但並不能說QQ的通信是不安全的,因為程序員可以 手動對UDP的數據收發進行驗證,比如發送方對每個數據包進行編號然後由接收方進行驗證啊什麼的,即使是這樣,UDP因為在底層協議的封裝上沒有採用類似 TCP的「三次握手」而實現了TCP所無法達到的傳輸效率。
10、Android socket 連不上伺服器
NetworkOnMainThreadException 你的網路請求應該放在一個單獨的線程中去執行,不能放在mainThread 也就是ui線程。