當前位置:首頁 » 安卓系統 » androidtcp源碼

androidtcp源碼

發布時間: 2022-10-14 22:19:24

⑴ TCP客戶端程序源代碼如何編寫

int client() { system("color 0a"); //修改DOS窗口顏色,是其成0A。 WORD wVersion=MAKEWORD(1,1); WSADATA wsData; int nResult= WSAStartup(wVersion,&wsData); //啟動WINSOCKET if(nResult !=0) { printf("啟動Winsock失敗!\n"); } SOCKET sc=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); //創建套接字 if(sc==INVALID_SOCKET) { printf("創建套接字失敗!\n"); } SOCKADDR_IN addrSc; addrSc.sin_family=AF_INET; addrSc.sin_port=htons(portNum); //保證位元組順序 char IP[20]; again: printf("請輸入伺服器的IP地址:"); gets(IP); if( -1==inet_addr(IP) ) //循環檢測IP地址是否合法 { printf("IP地址錯誤!\n"); goto again; } addrSc.sin_addr.S_un.S_addr=inet_addr(IP); int b=0; while(b<5) //檢測5次,如果伺服器在此時間內啟動,則進行連接 { nResult=connect(sc,(SOCKADDR*)&addrSc,sizeof(SOCKADDR)); //套接字連接 Sleep((DWORD)100); //延時1秒 if(nResult==SOCKET_ERROR) { printf(" %d 次連接失敗!\n",b+1); } else break; b++; } if(nResult==SOCKET_ERROR) { printf("登陸超時,請重新登陸!\n"); goto again; } char *buf="連接成功!"; //向服務端驗證連接成功 nResult=send(sc,buf,strlen(buf)+1,0); if(nResult==SOCKET_ERROR) { printf("5.套接字發送數據失敗!\n"); return 0; } char mess[M]; nResult =recv(sc,mess,strlen(mess),0); //接受服務端的連接驗證信息 if(nResult == -1 ) //判斷服務端是否關閉 { printf("\n服務端已斷開\n"); system("pause"); exit(0); } printf("%s\n",mess); tianle: system("cls"); //清屏 puts("\n\n"); puts(" * * "); puts(" * 歡·迎·使·用·局·域·網·文·件·發·送·工·具 *"); puts(" * (客 戶 端) * "); puts(" * * "); puts(" * * "); puts(" * 請等待服務端的相應操作 * "); puts(" * * "); puts(" * * "); puts(" * 天樂軟體工作室製作 * "); puts(" * 2008-3-1 * "); puts(" * 版權所有★歡迎傳播 * "); puts("全屏(退出全屏)操作請按:ALT+ENTER\n"); char rMess[100]; nResult=recv(sc,rMess,strlen(rMess),0); //接收服務端發來的操作請求 if(nResult==-1) //判斷服務端是否關閉 { printf("\n服務端已斷開\n"); system("pause"); goto tianle; } printf("%s\n",rMess); char ch; char str[100]; gets(str); ch=str[0]; while( ch!='Y' && ch!='y' && ch!='N' && ch!='n' ) //處理客戶端的錯誤輸入 { printf("輸入有誤,請重新輸入(Y/N):"); gets(str); ch=str[0]; } send(sc,&ch,sizeof(char),0); //向服務端反饋選擇,並執行相應操作 if(strcmp(rMess,"服務端向你傳送文件,是否接受(Y/N):")==0 && (ch=='Y' || ch=='y') ) { receiveFile(sc); } if(strcmp(rMess,"服務端向你發起聊天,是否接受(Y/N):")==0 && (ch=='Y' || ch=='y') ) { chatting_client(sc); } if(ch=='N' || ch=='n') { printf("你拒絕了!\n"); system("pause"); } system("cls"); goto tianle; nResult=closesocket(sc); //關閉套接字 if(nResult==SOCKET_ERROR) { printf("8.關閉套接字失敗!\n"); return 0; } }

滿意請採納

⑵ PC伺服器如何向Android模擬器發送一組字元串,急需具體代碼(tcp的)

public void testSendTcpPackage(){
try {
Log.d("TEST","Send again");
//ReceiveRtp receiveRtp = new ReceiveRtp();
//byte str[] = new byte[]{1,2,3,4,5,6,7,8,9,0};

int sended = 0;
int len = 1024;
Socket sender = new Socket("192.168.0.120", 5000);
byte[] data = new byte[len];
for(int i = 0; i< len; i++){
data[i] = (byte)i;
}
while(sended < 1000){

OutputStream os=sender.getOutputStream();
InputStream is = sender.getInputStream();
Log.d("TEST","Send data:" + sended);
os.write(data);
os.flush();
Thread.sleep(20);
len = is.read(data);
Log.d("TEST","read data:" + len);
sended++;

}
Log.d("TEST","Send finished");
sender.close();

} catch (Exception e) {
Log.d("TEST","Send again2");
// TODO Auto-generated catch block
e.printStackTrace();
}
}

⑶ 基於安卓的WIFI網路調試 助手,TCP客戶端的源碼 或者服務端

您好,對於您這樣的情況建議您下載最新版本的驅動軟體,更新到最新版本的驅動。

⑷ C# 和Android的 TCP(UDP)通信

伺服器程序
它僅僅建立ServerSocket監聽,並使用Socket獲取輸入輸出流。
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleServer {

/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub

//創建一個ServerSocket,用於監聽客戶端socket的連接請求
ServerSocket ss=new ServerSocket(30000);
//採用循環不斷接受來自客戶端的請求,伺服器端也對應產生一個Socket
while(true){
Socket s=ss.accept();
OutputStream os=s.getOutputStream();
os.write("您好,您收到了伺服器的新年祝福!n".getBytes("utf-8"));
os.close();
s.close();
}

}}

客戶端程序
package my.learn.tcp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.EditText;

public class SimpleClient extends Activity {
private EditText show;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
show = (EditText) findViewById(R.id.show);

try {

Socket socket = new Socket("自己計算機的IP地址", 30000);
//設置10秒之後即認為是超時
socket.setSoTimeout(10000);
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String line = br.readLine();

show.setText("來自伺服器的數據:"+line);

br.close();
socket.close();

} catch (UnknownHostException e) {
// TODO Auto-generated catch block
Log.e("UnknownHost", "來自伺服器的數據");
e.printStackTrace();
} catch (IOException e) {
Log.e("IOException", "來自伺服器的數據");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

⑸ Android socket源碼解析(三)socket的connect源碼解析

上一篇文章著重的聊了socket服務端的bind,listen,accpet的邏輯。本文來著重聊聊connect都做了什麼?

如果遇到什麼問題,可以來本文 https://www.jianshu.com/p/da6089fdcfe1 下討論

當服務端一切都准備好了。客戶端就會嘗試的通過 connect 系統調用,嘗試的和服務端建立遠程連接。

首先校驗當前socket中是否有正確的目標地址。然後獲取IP地址和埠調用 connectToAddress 。

在這個方法中,能看到有一個 NetHooks 跟蹤socket的調用,也能看到 BlockGuard 跟蹤了socket的connect調用。因此可以hook這兩個地方跟蹤socket,不過很少用就是了。

核心方法是 socketConnect 方法,這個方法就是調用 IoBridge.connect 方法。同理也會調用到jni中。

能看到也是調用了 connect 系統調用。

文件:/ net / ipv4 / af_inet.c

在這個方法中做的事情如下:

注意 sk_prot 所指向的方法是, tcp_prot 中 connect 所指向的方法,也就是指 tcp_v4_connect .

文件:/ net / ipv4 / tcp_ipv4.c

本質上核心任務有三件:

想要能夠理解下文內容,先要明白什麼是路由表。

路由表分為兩大類:

每個路由器都有一個路由表(RIB)和轉發表 (fib表),路由表用於決策路由,轉發表決策轉發分組。下文會接觸到這兩種表。

這兩個表有什麼區別呢?

網上雖然給了如下的定義:

但實際上在linux 3.8.1中並沒有明確的區分。整個路由相關的邏輯都是使用了fib轉發表承擔的。

先來看看幾個和FIB轉發表相關的核心結構體:

熟悉Linux命令朋友一定就能認出這裡面大部分的欄位都可以通過route命令查找到。

命令執行結果如下:

在這route命令結果的欄位實際上都對應上了結構體中的欄位含義:

知道路由表的的內容後。再來FIB轉發表的內容。實際上從下面的源碼其實可以得知,路由表的獲取,實際上是先從fib轉發表的路由字典樹獲取到後在同感加工獲得路由表對象。

轉發表的內容就更加簡單

還記得在之前總結的ip地址的結構嗎?

需要進行一次tcp的通信,意味著需要把ip報文准備好。因此需要決定源ip地址和目標IP地址。目標ip地址在之前通過netd查詢到了,此時需要得到本地發送的源ip地址。

然而在實際情況下,往往是面對如下這么情況:公網一個對外的ip地址,而內網會被映射成多個不同內網的ip地址。而這個過程就是通過DDNS動態的在內存中進行更新。

因此 ip_route_connect 實際上就是選擇一個緩存好的,通過DDNS設置好的內網ip地址並找到作為結果返回,將會在之後發送包的時候填入這些存在結果信息。而查詢內網ip地址的過程,可以成為RTNetLink。

在Linux中有一個常用的命令 ifconfig 也可以實現類似增加一個內網ip地址的功能:

比如說為網卡eth0增加一個IPV6的地址。而這個過程實際上就是調用了devinet內核模塊設定好的添加新ip地址方式,並在回調中把該ip地址刷新到內存中。

注意 devinet 和 RTNetLink 嚴格來說不是一個存在同一個模塊。雖然都是使用 rtnl_register 注冊方法到rtnl模塊中:

文件:/ net / ipv4 / devinet.c

文件:/ net / ipv4 / route.c

實際上整個route模塊,是跟著ipv4 內核模塊一起初始化好的。能看到其中就根據不同的rtnl操作符號注冊了對應不同的方法。

整個DDNS的工作流程大體如下:

當然,在tcp三次握手執行之前,需要得到當前的源地址,那麼就需要通過rtnl進行查詢內存中分配的ip。

文件:/ include / net / route.h

這個方法核心就是 __ip_route_output_key .當目的地址或者源地址有其一為空,則會調用 __ip_route_output_key 填充ip地址。目的地址為空說明可能是在回環鏈路中通信,如果源地址為空,那個說明可能往目的地址通信需要填充本地被DDNS分配好的內網地址。

在這個方法中核心還是調用了 flowi4_init_output 進行flowi4結構體的初始化。

文件:/ include / net / flow.h

能看到這個過程把數據中的源地址,目的地址,源地址埠和目的地址埠,協議類型等數據給記錄下來,之後內網ip地址的查詢與更新就會頻繁的和這個結構體進行交互。

能看到實際上 flowi4 是一個用於承載數據的臨時結構體,包含了本次路由操作需要的數據。

執行的事務如下:

想要弄清楚ip路由表的核心邏輯,必須明白路由表的幾個核心的數據結構。當然網上搜索到的和本文很可能大為不同。本文是基於LInux 內核3.1.8.之後的設計幾乎都沿用這一套。

而內核將路由表進行大規模的重新設計,很大一部分的原因是網路環境日益龐大且復雜。需要全新的方式進行優化管理系統中的路由表。

下面是fib_table 路由表所涉及的數據結構:

依次從最外層的結構體介紹:

能看到路由表的存儲實際上通過字典樹的數據結構壓縮實現的。但是和常見的字典樹有點區別,這種特殊的字典樹稱為LC-trie 快速路由查找演算法

這一篇文章對於快速路由查找演算法的理解寫的很不錯: https://blog.csdn.net/dog250/article/details/6596046

首先理解字典樹:字典樹簡單的來說,就是把一串數據化為二進制格式,根據左0,右1的方式構成的。

如圖下所示:

這個過程用圖來展示,就是沿著字典樹路徑不斷向下讀,比如依次讀取abd節點就能得到00這個數字。依次讀取abeh就能得到010這個數字。

說到底這種方式只是存儲數據的一種方式。而使用數的好處就能很輕易的找到公共前綴,在字典樹中找到公共最大子樹,也就找到了公共前綴。

而LC-trie 則是在這之上做了壓縮優化處理,想要理解這個演算法,必須要明白在 tnode 中存在兩個十分核心的數據:

這負責什麼事情呢?下面就簡單說說整個lc-trie的演算法就能明白了。

當然先來看看方法 __ip_dev_find 是如何查找

文件:/ net / ipv4 / fib_trie.c

整個方法就是通過 tkey_extract_bits 生成tnode中對應的葉子節點所在index,從而通過 tnode_get_child_rcu 拿到tnode節點中index所對應的數組中獲取葉下一級別的tnode或者葉子結點。

其中查找index最為核心方法如上,這個過程,先通過key左移動pos個位,再向右邊移動(32 - bits)演算法找到對應index。

在這里能對路由壓縮演算法有一定的理解即可,本文重點不在這里。當從路由樹中找到了結果就返回 fib_result 結構體。

查詢的結果最為核心的就是 fib_table 路由表,存儲了真正的路由轉發信息

文件:/ net / ipv4 / route.c

這個方法做的事情很簡單,本質上就是想要找到這個路由的下一跳是哪裡?

在這裡面有一個核心的結構體名為 fib_nh_exception 。這個是指fib表中去往目的地址情況下最理想的下一跳的地址。

而這個結構體在上一個方法通過 find_exception 獲得.遍歷從 fib_result 獲取到 fib_nh 結構體中的 nh_exceptions 鏈表。從這鏈表中找到一模一樣的目的地址並返回得到的。

文件:/ net / ipv4 / tcp_output.c

⑹ 如何搭建 android 開發環境

一.認識android的架構
Android其本質就是在標準的Linux系統上增加了Java虛擬機Dalvik,並在Dalvik虛擬機上搭建了一個JAVA的application framework,所有的應用程序都是基於JAVA的application framework之上。
android分為四個層,從高層到低層分別是應用程序層、應用程序框架層、系統運行庫層和linux核心層。
二.搭建環境
搭建開發環境
對國內的開發者來說最痛苦的是無法去訪問android開發網站。為了更好的認識世界,對程序員來說,會翻牆也是的一門技術,帶你去領略牆外的世界,好了,不廢話了, 國內開發者訪問(androiddevtools) 上面已經有了所有你要的資源,同時可以下載到我們的主角framework
但是這樣的搭建只能去閱讀源代碼,我們無法去更進一步去實現自己的rom,我們看到錘子的系統在早期的開放rom是自己從新實現了framework的代碼,現在看起來他成功了,所以我們還要去搭建android系統的源碼編譯環境。
搭建源碼編譯環境

三.開始主題
在一開始寫c程序的時候都有一個運行的入口,比如
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
//這里的main就是應用的入口
int main(int argc, const char * argv[]){
return 0;
}
在計算機網路原理中我們用socket實現一個伺服器端,不斷的接聽客戶端的訪問,而且他的代碼是這樣實現的:
#include <winsock2.h>
#pragma comment(lib, "WS2_32.lib")
#include <stdio.h>
void main()
{
WORD wVersionRequested;//版本號
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
//載入套接字型檔,如果失敗返回
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return;
}
//判斷高低位元組是不是2,如果不是2.2的版本則退出
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
return;
}
//創建流式套接字,基於TCP(SOCK_STREAM)
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
//Socket地址結構體的創建
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//轉換Unsigned long型為網路位元組序格
addrSrv.sin_family = AF_INET;//指定地址簇
addrSrv.sin_port = htons(6000);
//指定埠號,除sin_family參數外,其它參數都是網路位元組序,因此需要轉換
//將套接字綁定到一個埠號和本地地址上
bind(socSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//必須用sizeof,strlen不行
listen(socSrv, 5);
SOCKADDR_IN addrClient;//字義用來接收客戶端Socket的結構體
int len = sizeof(SOCKADDR);//初始化參數,這個參數必須進行初始化,sizeof
//循環等待接受客戶端發送請求
while (1)
{
//等待客戶請求到來;當請求到來後,接受連接請求,
//返回一個新的對應於此次連接的套接字(accept)。
//此時程序在此發生阻塞
SOCKET sockConn = accept(socSrv, (SOCKADDR*)&addrClient, &len);
char sendBuf[100];
sprintf(sendBuf, "Welcome %s to JoyChou",
inet_ntoa(addrClient.sin_addr));//格式化輸出
//用返回的套接字和客戶端進行通信
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多發送一個位元組
//接收數據
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\\n", recvBuf);
closesocket(sockConn);
}
}
他採用了一個while死循環去監聽客戶端的請求。

先上源代碼
public final class ActivityThread {
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
//從中可以看到為app開辟了一個線程進入了looper之中
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
看到源碼失望了,沒有一個while循環啊,其實用了他方法實現
//用一個looper的機制循環監聽響應
Looper.prepareMainLooper();
Looper.loop();
進一步深入代碼
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
// 在這里看到了一個循環監聽消息
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that ring the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}

⑺ 求一個Android studio 的 tcpip 客戶端收發的實例,希望大俠們能給一下源碼工程


最基礎的寫法


server端
publicclassMyTcpServer{
publicstaticvoidmian(String[]args){
try{
//構造一個伺服器端埠為12345的socket伺服器;
ServerSocketserverSocket=newServerSocket(12345);
//等待接收一個socket客戶端的連接,並得到客戶端的socket對象。
//此方法在沒有客戶端連接的時候,會阻塞。
Socketclient=serverSocket.accept();
//獲得socket客戶端的輸入管道
InputStreamis=client.getInputStream();
//獲得socket客戶端的輸出管道
OutputStreamos=client.getOutputStream();
byte[]buffer=newbyte[1024];
intlen=is.read(buffer);
System.out.println("-->"+newString(buffer));

os.write("Helloclient".getBytes());
os.flush();
is.close();
os.close();
client.close();
serverSocket.close();
}catch(IOExceptione){
e.printStackTrace();
}
}

}
client端
{
@Override
publicvoidrun(){
super.run();
try{
Socketclient=newSocket("192.168.3.173",12345);//IP為伺服器IP,埠號為伺服器埠號。
InputStreamin=client.getInputStream();
OutputStreamout=client.getOutputStream();

out.write("Helloserver".getBytes());//如果在伺服器端先進行讀操作。那麼客戶端就應先進行寫操作。
//這樣交替進行,不然將都阻塞在Read讀操作。
out.flush();

byte[]buffer=newbyte[1024];
intlen=in.read();
in.read(buffer);
System.out.println("--->"+newString(buffer));


}catch(IOExceptione){
e.printStackTrace();
}
}
}
}

c語言跟android的tcp數據傳輸問題

private String floadText(String name) { // TODO Auto-generated method stub String str=null; try { File fl=new File("/sdcard/"+name); byte[] by1=new byte[(int)fl.length()]; FileInputStream fs1=new FileInputStream(fl); fs1.read(by1); fs1.close(); str=new String(by1,"utf-8"); str=str.replaceAll("\\r\\n", "\n"); } catch (Exception e) { Toast.makeText(getBaseContext(), "sorry not find this file!", Toast.LENGTH_SHORT).show(); } return str; }

熱點內容
怎麼上傳歌曲到qq音樂 發布:2025-01-24 00:45:30 瀏覽:64
養貓用什麼配置 發布:2025-01-24 00:37:58 瀏覽:811
pythongps 發布:2025-01-24 00:37:51 瀏覽:812
辦公編程滑鼠 發布:2025-01-24 00:37:07 瀏覽:385
wpa加密類型 發布:2025-01-24 00:35:58 瀏覽:959
如何用批處理實現ftp映射盤符 發布:2025-01-24 00:25:45 瀏覽:953
win7sql版本 發布:2025-01-24 00:22:16 瀏覽:498
安卓手機市場有什麼 發布:2025-01-23 23:48:56 瀏覽:25
銀城醫考能緩存的視頻 發布:2025-01-23 23:44:51 瀏覽:542
智能電視linux 發布:2025-01-23 23:42:54 瀏覽:843