当前位置:首页 » 安卓系统 » 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; }

热点内容
少儿编程排行 发布:2025-01-24 04:40:46 浏览:697
搭建服务器怎么使用 发布:2025-01-24 04:19:34 浏览:443
平行进口霸道哪些配置有用 发布:2025-01-24 04:19:32 浏览:873
ngram算法 发布:2025-01-24 04:03:16 浏览:658
迷宫游戏c语言 发布:2025-01-24 03:59:09 浏览:357
荣耀30pro存储类型 发布:2025-01-24 03:54:02 浏览:556
客户端文件上传 发布:2025-01-24 03:48:44 浏览:257
推特更改密码的用户名是什么 发布:2025-01-24 03:45:55 浏览:596
cc编译选项 发布:2025-01-24 03:45:18 浏览:511
银行密码怎么被锁 发布:2025-01-24 03:37:02 浏览:431