androidcsocket
① android socket通信延迟怎么解决
Handle 吧,
② android 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怎样实现断网重连
由于当网络出现故障时,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 进行通信.
第一个问题:这是可以的,android通过socket访问本机服务器PC, ip是10.0.2.2。
第二哥问题:用ServerSocket建立一个对象 ServerSocket serverSocket = new ServerSocket(serverListenPort, connectionMaxLength, InetAddress.getByName(serverIpString));
再加一个监听Socket incoming = serverSocket.accept();就可以检测客户端发过来的连接请求,之后使用流就可以完成他们之间的通信了。
原创手打,thanku
⑤ android socket请求数据怎么抓包
从网络上面搜索到的资料看,要抓取手机中app的网络包有下面几种方式:
(1).将tcpmp移植到Android平台,然后在命令行下启动tcpmp进行抓包。Tcpmp程序实际上可以看作是wireshark的命令行版本,将该程序移植到Android平台直接抓包,这是一种最直接的抓包方式,然后将抓获的数据包文件,从手机传到windows系统上用wireshark打开进行分析,这种方式貌似不能用于苹果手机。
(2).使用fiddler,在windows系统上打开fiddler软件,该软件会将我们的电脑变成一个代理,然后在手机上设置wifi网络,将代理指定为开启fiddler的那台电脑,并且端口设置为fiddler侦听的8888端口,这时候使用手机访问的数据,就会通过该代理,在fiddler中就可以看到http的数据包。这种方法我试了半天怎么都看不到数据包,不知道哪里出问题了,根据原理,这种方式支持可以通过代理访问网络的手机。所以从原理上说是支持Android和苹果手机的。
(3).通过各种方式在pc电脑上建立wifi热点,然后使用wireshark在pc电脑上监视该wifi热点,通过手机连接该热点访问网络。这样wireshark会获取所有流经该热点的数据包这种方式适用于所有能够无线访问的手机,也就是说所有的Android和苹果手机。
那么如何在pc电脑上建立wifi热点呢,有这么几种办法:
(1).Win7电脑经过设置,可以将无线网卡设置为wifi热点,这种方法我以前用过,可以成功,但是步骤繁琐,而且不一定能够成功,其他的windows系统估计就没戏了。
(2).使用软件自动建立wifi热点,不需要自己手工配置,这样的软件有Connectify Hotspot,猎豹免费wifi,360免费wifi软件,这几个软件我都使用过,比较好用,这种方式同样也只能针对有无线网卡的笔记本电脑,原理也是将笔记本电脑上的无线网卡建立热点了,只不过是软件自动的,不需要人工设置,比方法1要方便。
注意:经过实验发现,手机连接这种方式建立的热点,所发送的数据,用wireshark去抓包,需要捕获电脑上本身联网的那个“网络连接”,例如我的笔记本上面有一个“本地连接”,该连接是使用有线网络的。我用猎豹免费wifi软件建立一个热点之后,我的电脑上多出一个“无线网络连接3”,可以看到该“无线网络连接3”是猎豹生成的,但是我抓包的时候,wireshark需要捕获“本地连接”上的包,也就是我的手机访问的数据实际上还是使用的“本地连接”,通信IP也是“本地连接”上的IP地址,而在手机的wifi连接设置中看到的ip地址,在我抓的包中也搜不到,也就是说手机通过该热点访问网络,实际上还是使用的“本地连接”的IP地址,至于是什么原理,我目前也不太清楚。但是下面要说的随身wifi硬件则与此不同,随身wifi是建立了网卡。
(3).使用随身wifi硬件。这种也是很方便的方法,而且比较稳定,对笔记本电脑和台式机都可以使用。我之前买了一个360的随身wifi(不是打广告,本人对360公司不感冒,但是他的随身wifi做的确实还可以,同事中有买小米wifi的,不太稳定)。只要在360的官网上下载驱动,直接插上随身wifi就可以使用,我推荐使用这种方法。
如果你用的是笔记本电脑可以使用方法2,如果是台式机器可以使用方法3。
⑥ 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;
}
⑦ android socket 问题。。。。。
输出到result2
说明“socket.receive(packet);”这句有问题啊,检查下socket 啊!
我还没学android的东西,就是靠java知识联想的,希望对你有帮助。
以前在java中用socket的时候也经常出现类似的错误,多调试多测试,加油啊
你可以debug一下试试啊,看看是哪里的问题
⑧ Android socket通信能发数据但不能接收到数据
我C#项目中做过同样的Android移动Socket通信。
Android客户端:
SocketClient对象receive函数就调用读取函数,当然之前是打开了Socket连接。
publicStringreceive()throwsIOException{
BufferedReaderreader=newBufferedReader(
newInputStreamReader(client.getInputStream()));
Stringtxt=reader.readLine();
returntxt;
}
Activity页面使用任务不间断监听接收。
<Void,Void,Void>{
@Override
protectedVoiddoInBackground(Void...arg0){
SocketClientclient=SocketClient.getInstance();
while(true)
{
try{
Thread.sleep(5000);
Stringre=client.receive();
if(re==null||(re!=null&&re.equals(""))){
continue;
}
if(isCancelled())
returnnull;
//TODO:处理接收到消息
}catch(SocketExceptione){
//服务端断开,启动重连任务
if(e.getMessage().contains("ECONNRESET")){
reconnectTask=newReconnectServerTask();
reconnectTask.execute((Void)null);
}
returnnull;
}catch(IOExceptione){
e.printStackTrace();
}catch(InterruptedExceptione){
e.printStackTrace();
}catch(Exceptione){
e.printStackTrace();
}
}
}
}
⑨ android socket 异常退出问题
你没有用线程!!!
--------------------
客户Socket
产生Socket对象,客户端连接服务端的端口,这也需要放到线程中,由newSocket()子程序负责; 读Socket得到的字符串通过消息传给主程序协助显示,这由clientRead(Socket sk)子程序负责,这两个耗时性子程序都要放到子线程才能工作, clientRead(final String ip,final int port)产生即时子线程供调用。
Socket newSocket(String ip,int port)
{ Socket sk=null;
try
{ sk=new Socket(ip,port); // 连接服务端,返回Socket
}
catch(Exception e)
{
}
return(sk);
}
void clientRead(Socket sk)
{ // 客户端读Socket
DataInputStream inf;
try
{ inf=new DataInputStream(sk.getInputStream());
while(sk.isConnected() && !sk.isClosed())
{ String s=inf.readUTF();
if (s.length()>0)
{ Message msg=cHandler.obtainMessage(2,s);
cHandler.sendMessage(msg);
}
}
}
catch(Exception e)
{
}
}
void clientRead(final String ip,final int port)
{ // 子线程中客户端读Socket
new Thread(new Runnable()
{ @Override
public void run()
{ Socket sk=newSocket(ip,port);
clientSocket=sk;
if (sk!=null)
clientRead(sk);
}
}).start();
}
一次成功的连接,在服务端与客户端各自都会产生一个Socket对象,并包含了许多方法与属性,对象中可以知道对方的IP地址与端口,还有判断连接状态的函数,如Socket.isConected()和Socket.isClosed(),但这只能判断自已的Socket是否已连接与断开,但无法判断对方的是否断开状态,解决的办法是服务端向对方发“心跳包”或自行在对话协议中向对方发应答命令,以是否响应超时作为判断对方是否断开的依据。
⑩ Android Socket通信开发,求详细过程,附加注释,谢谢
服务端往Socket的输出流里面写东西,客户端就可以通过Socket的输入流读取对应的内容。Socket与Socket之间是双向连通的,所以客户端也可以往对应的Socket输出流里面写东西,然后服务端对应的Socket的输入流就可以读出对应的内容。
Socket类型为流套接字(streamsocket)和数据报套接字(datagramsocket)。
Socket基本实现原理
TCP与UDP
1基于TCP协议的Socket
服务器端首先声明一个ServerSocket对象并且指定端口号,然后调用Serversocket的accept()方法接收客户端的数据。accept()方法在没有数据进行接收的处于堵塞状态。(Socketsocket=serversocket.accept()),一旦接收到数据,通过inputstream读取接收的数据。
客户端创建一个Socket对象,指定服务器端的ip地址和端口号(Socketsocket=newSocket("172.168.10.108",8080);),通过inputstream读取数据,获取服务器发出的数据(OutputStreamoutputstream=socket.getOutputStream()),最后将要发送的数据写入到outputstream即可进行TCP协议的socket数据传输。