‘壹’ 请问开发android的朋友,怎么样在tcp socket中建立长连接,好像只能在线程里建立连接,线程关闭了就断了。
后台开启一个线程一直运行,每隔1分钟左右发送一个心跳报文给服务器,以确保时刻跟服务器链接。若超过3次服务器未对客户端发送的心跳报文做出回应则重新链接。 如果这么作的话,必须确保和服务器达成一定的应用层协议。
‘贰’ Android中TCP客户端怎么可以及时判断与服务端的异常断开呀 我想在客户
直接用BufferedReader
如果readLine() 返回为null的话, 表示socket已经断开连接了, 因为readLine() 是阻塞的, 就是等服务器的数据输出, 一直等到返回了回车换行, 才会继续执行。
‘叁’ Tcp,android客户端服务端断开重连应该怎么个实现
我正好也在做这方面的东西,我们可以交流一下,我这边需要做的是TCP客户端和TCP服务器,无这边服务器搭建目前运行状况良好,但是客户端始终不行,请问你有没有客户端的相关例程,我这边的例程也可以分享给你的说,大家相互借鉴,共同进步。
周末加了一天班,终于把问题解决了,总结一个血的教训给你,就是:你在调试单片机客户端的时候,作为服务器的电脑防火墙一定要关掉啊,我就是因为这样,白忙了两天。
你要实现客户端断开不影响HTTP服务器的运行,就需要建立两个不同的TCP_SERVER_pcb和TCP_CLI ENT_pcb结构体,分别用于客户端和服务器的TCP/IP协议栈控制。并且需要两个不同的发送和接收缓存,不然是不行的。
‘肆’ android socket用TCP方式client端怎么监听服务器发送来的数据
服务器端就是需要一个循环不停的接收,这样才能保证服务器能一直监听客户端传过来的数据
你这是同步的,如果用异步socket的话,BeginReceive里面注册了一个回调函数,在回调里面再次调用BeginReceive就可以一直监听了
‘伍’ 关于Android tcp连接
安卓的主线程中是不能用耗时性的操作读写,所以,把SOCKET读写操作都要放到线程中。
可以用即时线程的办法。参考我的SOCKET客户端。
//--------Socket服务端----------------------
void dispClients()
{ //显示所有客户
int n=vector.size();
String ss="\n"+n+" clients:\n";
for (int i=0;i<vector.size();i++)
{
Socket sk=vector.get(i);
String ip=sk.getInetAddress().toString();
String port=""+sk.getPort();
ss+=""+ip+","+port+"\n";
}
textView1.setText(ss);
}
void writeSocket(Socket sk,String s)
{ // 向客户端Socket发字符串
DataOutputStream outf;
try
{
outf=new DataOutputStream(sk.getOutputStream());
if (!sk.isClosed())
outf.writeUTF(s);
}
catch(Exception e)
{
try
{
setTitle("err");
sk.close(); // 对方已关闭
}
catch(Exception e1)
{
}
}
}
void writeSock(final Socket sk,final String s)
{ // 子线程中向客户端Socket发字符串
new Thread(new Runnable()
{
@Override
publicvoid run()
{
writeSocket(sk,s);
}
}).start();
}
void sendAll(final String s)
{ // 向所有管理中的客户Socket发串
boolean del=false;
for (int i=0;i<vector.size();i++)
{
Socket sk=vector.get(i);
if (sk.isClosed())
{
vector.remove(i); // 已断开的连接
del=true;
}
else
writeSock(sk,s);
}
if (del)
{ // 客户端有变化,通知主程序刷新显示
Message msg=sHandler.obtainMessage(0,"");
sHandler.sendMessage(msg);
}
}
void readSocket(Socket sk)
{ // 服务端读Socket
DataInputStream inf;
try
{
inf=new DataInputStream(sk.getInputStream());
while(sk.isConnected() && !sk.isClosed())
{
String s=inf.readUTF();
if (s.length()>0)
{ // 读到字符串后,通知主程序处理
String ip=sk.getInetAddress().toString();
String port=""+sk.getPort();
s=ip+","+port+":"+s+"\n";
Message msg=sHandler.obtainMessage(1,s);
sHandler.sendMessage(msg);
}
}
}
catch(Exception e)
{
}
}
void readSock(final Socket sk)
{ // 子线程中读
new Thread(new Runnable()
{
@Override
publicvoid run()
{
readSocket(sk);
}
}).start();
}
void listen(ServerSocket ssk) // 接受多个客户端连接请求
{
while (!ssk.isClosed())
try
{
Socket sk=ssk.accept();
vector.add(sk); // 有客户连接
readSock(sk);
// 通知刷新客户列表
Message msg=sHandler.obtainMessage(0,"");
sHandler.sendMessage(msg);
}
catch(Exception e)
{
}
}
void listen() // 线程接受多个客户端连接请求
{
new Thread(new Runnable()
{
@Override
publicvoid run()
{
listen(serverSocket);
}
}).start();
}
//---------Socket客户端----------------------------------
cHandler=new Handler()
{ // 客户端消息处理器
@Override
public void handleMessage(Message msg)
{
String s=msg.obj.toString();
textView2.append(s);
}
};
clientRead("127.0.0.1",9003);
// clientRead("10.0.2.15",9003);
textView2=(TextView)findViewById(R.id.textView2);
textView2.setText("");
editText1=(EditText)findViewById(R.id.editText1);
button1=(Button)findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
try
{
String s=editText1.getText().toString();
writeSock(clientSocket,s);
}
catch(Exception e)
{
}
} //public
});
button2=(Button)findViewById(R.id.button2);
button2.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
try
{
clientSocket.close();
String s="中华人民共和国";
Message msg=sHandler.obtainMessage(1,s);
sHandler.sendMessage(msg);
}
catch(Exception e)
{
}
} //public
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{ // 按返回键的退出处理
if (keyCode == KeyEvent.KEYCODE_BACK )
{
try
{ // 防止出现端口已绑定的错误
serverSocket.close();
finish();
System.exit(0);
}
catch(Exception e)
{
}
}
return(false);
}
‘陆’ 我怎样才能连接与亚行至Android通过TCP
手动处理 从您的设备,如果它是植根 根据对XDA开发后,您可以启用adb通过WiFi从装置su
setprop service.adb.tcp.port 5555
stop adbd
start adbd
并且您可以禁用它,并返回亚行与监听USBsetprop service.adb.tcp.port -1
stop adbd
start adbd
从电脑,如果你有USB连接已经 这是更容易切换无线网络,如果你已经有了USB访问。从该行已在设备通过USB接口,连接问题adb tcpip 5555
adb connect 192.168.0.101:5555
一定要更换192.168.0.101与实际分配给您的设备的IP地址。 告诉亚行后台程序返回到监听通过USBadb usb
应用自动化进程 也有在谷歌播放的自动执行此过程的几个应用程序 CodeGo.net,快速搜索建议adbWireless,支持WiFiadb和adb的WiFi。所有这些都需要root权限,但adbWireless需要更少的权限。
2. 这是非常简单的。 首先确保你的手机是植根。 从市场上下载一个终端仿真器(有很多是free的)。 请确保您的Android连接到您的无线网络,并获得无线IP地址。 打开终端程序并键入:su
setprop service.adb.tcp.port 5555
stop adbd
start adbd
现在去(假设你视窗)在桌面上创建一个快捷方式为“cmd.exe的”(不含引号)。 右键单击CMD快捷方式并选择"Run as Administrator"改变你的android-sdk-windows\tools folder类型:adb connect ***wifi.ip.address***:5555
(example: adb connect 192.168.0.105:5555)
亚行现在应该说你已连接。 注意:如果你太快给它可能会失败。所以,如果你说这是行不通的尝试至少2 5秒钟的时间间隔。
3. 我知道这是旧的,但我想补充我的2美分- 我需要得到两个USB和TCPIP工作的adb(不要问),所以我做了以下(使用方向其他人张贴的XDA开发) 运用adb shell:su
#set the port number for adbd
setprop service.adb.tcp.port 5555
#run the adbd daemon *again* instead of doing stop/start, so there
#are 2 instances of adbd running.
adbd &
#set the port back to USB, so the next time adb is started it's
#on USB again.
setprop service.adb.tcp.port -1
exit
4. 正如布赖恩说: 根据对XDA开发后,您可以启用adb通过WiFi从装置 对应setProp service.adb.tcp.port 5555 停止adbd 启动adbd 并且您可以禁用它,并返回亚行与监听USB 对应setProp service.adb.tcp.port-1 停止adbd 启动adbd 如果你有USB连接已经,它是更容易切换无线网络。从该行已在设备通过USB接口,连接问题 亚行TCPIP 5555 ADB连接192.168.0.101:5555 告诉亚行后台程序返回到监听通过USB 也有在Android Market上的几个应用程序能自动完成这些过程。 它works.You只需要访问Android shell,然后输入 另外一个(容易)解决方案是目前市场上:adbWireless,它会自动设置您的手机。 根是必须的!为...
5. 从adb --helpconnect <host>:<port> - connect to a device via TCP/IP
顺便说那行选项。 你应该尝试将手机连接到你的无线网络,然后得到它的IP从您的路由器,它不会工作,对 端口是5554
6. 您保存的adb路径到您的Windows路径 在Android激活调试模式 连接到PC 提示(有管理员右)类型:adb的TCPIP 5555 断开平板电脑,或从电脑智能手机 提示符下键入:ADB连接IPADDRESS(IP地址为您的平板电脑或智能手机的DHCP / IP地址,您可以通过无线网络找到->电流 现在,提示你应该看到类似的结果:连接到xxx.xxx.xxx.xxx:5555
7.adb tcpip 5555
奇怪,但是这只是工作,如果我有USB电缆连接,然后我就可以拔掉,并为它去与一切ADB。 而返回时,adb usb
只会工作连接。 没关系,如果我发出setprop service.adb.tcp.port 5555
或setprop service.adb.tcp.port -1
然后停止和启动adbd,我仍然需要电缆或这是行不通的。 所以,如果我的亚行不工作,我敢打赌,我将无法使亚行通过WiFi两种。
8. 你可以ssh本地端口转发。但它仍然涉及电缆。 您的USB连接(主机)与一个sshd运行。 在远程(游客)个人电脑开始能够portforwarding /隧道的ssh客户端端。 例如:砰砰-L 5037:本地主机:5037 这种结构给我的设备连接到虚拟机。 到是不够稳定(在调试过程中) SSH隧道工程为自由和更可靠。
9. 我不知道如何连接的设备,而在所有的任何一个USB连接,但如果你能,也许在您连接它可以通过发出切换adbd到TCP模式adb tcpip <port>
从终端,从任何PC上通过连接到您的设备通过WiFi:adb connect <ip>:<port>
也许也有可能从该装置上的终端切换到TCP模式。
10. 我觉得其他的答案就简单得多了adbWireless: 只需在手机上安装一个应用程序切换调试通过wifi,安装一个Eclipse插件,你就大功告成了。
11. 要连接您的TCP端口 请确保您的系统和设备连接到网络 1。打开控制台的cmd.exe 2,型号ADB TCPIP 5555 3。至系统->选项-> USB调试unchek它TCPIP连接 4.type ADB连接192.168.1.2这是您的设备ip地址 5。连接到192.168.1.2 如果你错误:未找到设备 连接设备到系统然后按照 为扎根设备 对应setProp service.adb.tcp.port 5555 停止adbd 启动adbd
12. 在我的系统是这样的: 我在我的Linux shell中的Android设备,一个简单的“使用ifconfig”没有我的IP地址。我只好类型: 用ifconfig eth0 -或- 加上netcfg 让我的IP地址。 (我知道是eth0的配置,我看到它在我的dmesg)然后我做了: 对应setProp service.adb.tcp.port-1 停止adbd 启动adbd 然后在我的Win7盒(一个运行Eclipse 3.7.1)。我打开提示 \\ Android的SDK \\平台工具> 没有以管理员身份运行。然后我做了一个 ADB连接12.345.678.90 我从来没有把一个端口。如果我做了 亚行TCPIP 5555 它说,它无法找到该设备,然后没有出现在我的“亚行的设备”列表中。即这只是工作,如果我不这样做上面。 我可以做一个“亚壳”与我的Android设备。但我的Android设备不现在出现在我的运行->运行配置-> Target选项卡。在另一方面,如果我把目标选项卡设置为自动。后来,当我通过运行我的应用程序运行->运行它并运行我的Android设备上,即使我的Android设备甚至没有列为我的目标之一。
13. 要使用TCP和USB模式之间切换只需你可以将它添加到/init.rc:on property:service.adb.tcp.port=*
restart adbd
on property:service.adb.tcp.enable=1
setprop service.adb.tcp.port 5555
on property:service.adb.tcp.enable=0
setprop service.adb.tcp.port -1
现在你财产service.adb.tcp.enable启用或禁用侦听端口5555。运行netstat以检查它是否在听。正如你可以看到它也会触发,如果你想改变service.adb.tcp.port手动。
14. 使用adbwireless应用程序,使手机,亚行从Windows机器连接到它对话。在手机上的应用程序adbwireless告诉你如何连接到它,给人的IP地址和一切。 要少得多有趣的选择是通过USB进行连接,告诉亚行通过TCPIP 5555手机TCPIP,然后断开USB,ADB连接。这是更难通过这种方式,你必须找出手机的IP地址,你自己(adbwireless告诉你的IP),你必须通过USB进行连接,你必须运行adb的TCPIP(adbwireless需要的是照顾过)。 所以:在手机上安装adbwireless。使用它。这是可能的,我这样做经常在Linux和Windows上。
15. 我放在一起自动启用和通过TCP连接adb,通过USB连接的设备的批处理文件。有了它,你不必把在IP手动。@echo off
setlocal
REM Use a default env variable to find adb if possible
if NOT "%AndroidSDK%" == "" set PATH=%PATH%;%AndroidSDK%\platform-tools
REM If off is first parameter then we turn off the tcp connection.
if "%1%" == "off" goto off
REM Set vars
set port=%1
set int=%2
if "%port%" == "" set port=5557
if "%int%" == "" set int=wlan0
REM Enable TCP
adb -d wait-for-device tcpip %port%
REM Get IP Address from device
set shellCmd="ip addr show %int% | grep 'inet [0-9]{1,3}(\.[0-9]{1,3}){3}' -oE | grep '[0-9]{1,3}(\.[0-9]{1,3}){3}' -oE"
for /f %%i in ('adb wait-for-device shell %shellCmd%') do set IP=%%i
REM Connect ADB to device
adb connect %IP%:%port%
goto end
:fail
echo adbWifi [port] [interface]
echo adbWifi off
goto end
:off
adb wait-for-device usb
‘柒’ android怎么实现tcp数据传输
Socket s = new Socket("192.168.1.1",5200)//"ip",port
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
InputStream in = s.getInputStream();
byte[] b = new byte[in.available];
in.read(b);
String str = new String(b);
out.print("收到"+s);
out.flush();
‘捌’ 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所无法达到的传输效率。
‘玖’ android tcp通信接收数据就闪退的原因
内存不足导致的闪退。比如说androidtc内存没有释放,一长条列表下有N个资源需要展示,不断下拉,上面的资源没有释放,所分配的内存越来越多,最后当然会闪退。
‘拾’ android设备怎么设置tcpip
1. 使用USB数据线连接设备(此方法需配置adb环境变量,也可直接进入adb工具目录执行\android-sdk-windows\platform-tools\)。
2. 命令输入adb tcpip 5555 ( 5555为端口号,可以自由指定)。
3. 断开 USB数据,此时可以连接你需要连接的USB设备。
4. 再命令输入 adb connect <设备的IP地址>:5555
后面就可以使用ADB ,DDMS 来调试Android应用或显示Logcat 消息。
5. 如果需要恢复到USB数据线,可以在命令行输入adb usb
注: Android设备的IP地址可以通过(设置->关于手机->状态信息)查看