重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
android中的tcp和udp不需要任何权限。因为它们都是网络通讯协议的一种,只要手机没有问题,能够上网,就可以使用TCP和UDP协议了。
从网站建设到定制行业解决方案,为提供做网站、网站设计服务体系,各种行业企业客户提供网站建设解决方案,助力业务快速发展。成都创新互联公司将不断加快创新步伐,提供优质的建站服务。
TCP/IP是用于电脑通信的一组协议,我们通常称之为TCP/IP协议族,它是七十年代中期美国国防部为其ARPANET广域网开发的网络体系结构和协议标准,以它为基础组建的Internet是目前国际上规模最大的电脑网络,正因为Internet的广泛使用,使得TCP/IP成了事实上的标准。之所以说TCP/IP是一个协议族,是因为TCP/IP协议包括TCP、IP、UDP、ICMP、RIP、TELNET、FTP、SMTP、ARP、TFTP等许多协议,这些协议统称为TCP/IP协议。
TCP/IP协议的名字实际上是来自最重要的两个协议,TCP(传输控制协议)和IP(网际协议)。它负责把需要传输的信息分割成许多小包,也叫做信息包,然后把这些信息包发往目的地,它能有效地保证传输的安全性和正确性。
在Internet内部,信息不是以一个恒定的流从主机传送到主机,而是把数据分解成小包,即数据包进行传送。例如你传送一封很长的信件给你的朋友,TCP就可以把这些信息分成很多个数据包,每个数据包用一个序号和一个接收地址来标定。此外,TCP还插入一些纠错信息。
接着数据包被传过网络,这就是IP的工作,即把它们传送给远程主机。在另一端,TCP接收到数据包并核查错误。如果有错误发生,TCP可以要求重发这个特定的数据包。只要所有的数据包都被正确地接收到,TCP将用序号来重新构造原始信息。换句话说,IP的工作是把原始数据从一地传送到另一地,TCP的工作是管理这种流动并确保其数据是正确的。ß把数据分解成数据包有很多好处。首先,它允许Internet让很多不同的用户在同一时刻使用同一通讯线路。因为这些数据包不必一起输送,所以通讯线路可以载着所有类型的数据包按它们自己的路径从一地到另一地。就如一条高速公路上各个汽车都在公路上行驶。ß用数据包传输的另一个好处是:当某处出错,只需重新传送单个数据包,而不是整个信息,这样会大大加快Internet的传输总速度。
TCP/IP是把电脑和通讯设备组织成网络的协议大家庭,两个最重要的协议是TCP和IP。IP从一地到另一地传输数据,而TCP则保证它们都正确地工作。
目前,遍布世界范围的Internet网络主要采用的就是TCP/IP协议,而且,国内大多数网络建设现在已朝着TCP/IP协议的方向发展。
tcp和udp都是网络传输协议, 和android没有直接关系。所有基于网络访问的过程都可能涉及这2个协议。简单来讲:tcp是可靠连接,即传输的数据必须完整,如用户登录的信息的验证; udp是不可靠连接,即传输过程不能保证数据的完整性,如语音聊天,当网络条件不好时,可能会丢失内容。
安卓的主线程中是不能用耗时性的操作读写,所以,把SOCKET读写操作都要放到线程中。
可以用即时线程的办法。参考我的SOCKET客户端。
//--------Socket服务端----------------------
void dispClients()
{ //显示所有客户
int n=vector.size();
String ss="\n"+n+" clients:\n";
for (int i=0;ivector.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;ivector.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);
}
之前已经讲过了tcp客户端的实现了,大家有兴趣的话,可以参看文章
Android上实现TCP客户端
那么,今天我们就来讲讲tcp之服务端的封装吧。我已经将tcp服务端封装成了一个类—TcpServer,下面就来讲讲它的使用吧。
今天涉及内容:
先来波效果图
在 tcp服务端 建立 ServerSocket 的时候,我们通常是这样的:
其实以上方法调用的是
其中涉及到的参数:
鉴于tcp服务端 ServerSocket 一般运行在 "本机" 上,则快速初始化 ServerSocket 运用上面的方法:
意思是建立的ServerSocket IP地址为本机,可容纳socket个数为 50 。
在理解了 ServerSocket 初始化问题后,让我们来看看封装类TcpServer的几个主要方法:
TcpServer 主要是在 java 上运行,所以就让我们在 Androidstudio 上模拟下在 Java 中运行tcp服务端的场景:
这里涉及到的两个类 SocketConfig 和 SocketHelper 和之前的一样,大家可以参考文章 Android上实现TCP客户端 中与之相关的介绍,这里就不赘述了。
tcp服务端主要容易出现以下两个问题:
对于第一个问题,这里需要强调的是 TcpServer 的接收方法 receiveMessage(String charsetName) 是以 (result = bufferedReader.readLine()) != null 做判断读取 stream 的,所以客户端向 TcpServer 发送消息时,需要在结尾加上\n,这样 TcpServer 的receiveMessage(String charsetName)方法才能将传过来的数据接收完整。
对于第二个问题,则需要客户端与服务端设置相同的字符集以保证数据不乱码。
封装类 TcpServer 源码如下:
Http是应用层协议,TCP是网络层协议,应用层在TCP/IP四层架构中位于TCP的上一层。
建立Http连接在实现时有以下两种方式:
1、[java] view plaincopy
DefaultHttpClient http = new DefaultHttpClient();
HttpGet method = new HttpGet(url);
HttpResponse response =http.execute(method);
2、[java] view plaincopy
URL url = new URL(uri);
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
connection.connect();
而TCP连接在实现时要借助Socket(套接字 IP+端口号)
[java] view plaincopy
Socket s = new Socket("localhost", 12345);
区别从这两个连接的实现方式就可以看出来,HTTP连接需要指明资源的URL,发出请求的应用不知道服务器的IP,虽然域名服务器也是要把域名解析成IP地址,但不属于应用所关心的范畴,是网络层应该完成的工作。所以Http连接属于无状态的短连接,若再请求其他数据,需要再重新建立连接。客户端向服务器发送请求后,服务器才知道客户端的存在。
TCP连接实现时需要指明IP地址和端口号,就可以跟目的主机通过三次握手建立联系,该连接一直保持直到某一方提出取消连接,通过四次握手关闭连接。Socket支持TCP/UDP协议,如果使用TCP协议,那么socket连接就是TCP连接。论文提到的应用场景是手机与云端的服务器建立联系,因为要保持连接并指定连接的建立时间,所以在这种场景下使用TCP连接最合适。3G网络不支持端到端建立TCP连接,因为它是client-server模式,所以需要通过云端服务器的辅助来实现手机的端到端通信。