------- android培训、java培训、期待与您交流! ----------
网络通信需要四个通信层,分别是应用层(http、ftp)、传输层(tcp、udp)、网际层(IP)、主机到网络物理层。
UDP协议将数据及源和目的封装成数据包中,不需要建立连接,每个数据包的大小限制在64k内,因为无连接,所以是不可靠的协议。但同样因为不需要建立连接,所以速度较快。而TCP协议,需要建立连接,形成传输数据的通道。在连接中进行大数据量传输。因为在通信前必须通过三次握手万恒连接,所以是可靠协议。但是也同样因为必须建立连接,所以效率会稍低。
我们要获取一个机器的对象可以用Ineti=InetAdress.getLocalHost()来获取本机对象,或者用Inet i=InetAdress.getByName(String name)来获取已知机器名的主机对象。
Socket就是为网络服务提供的一种机制。通信的两端都有Socket,网络通信其实就是Socket间的通信。数据在两个Socket间通过IO传输。
小练习,通过UDP传输方式,将一段文字数据发送出去。思路:1,建立updssocket服务。2,建立数据,并将数据封装到数据包中。3,通过socket服务的发送功能将数据包发送出去。4,关闭资源。具体代码如下
DatagramSocketds=new DatagramSocket();
byte[] buf=”hehhehhe”.getBytes();
DatagramPacketdp=
new DatagramPacket(buf,buf.length,InetAddress.getByName(“192.168.1.1”),10000);
//封装了buf数组中所有长度的数据,目的主机为192.168.1.1,端口为10000
ds.send(dp);
ds.close();
那么同样来定义一个应用程序用来接受UDP协议传输的数据并处理。思路:1,定义udpsocket服务,通常都会监听一个端口,其实就是给这个接受网络应用程序定义数字标识。2,定义一个数据包,因为要存储接受到的字节数据。因为数据包中有很多功能可以提取字节数据中的不同数据信息。3,通过socket服务的receive方法将受到的数据存入已经定义好的数据包中。通过数据包对象特有功能,将这些不同的数据取出。5,关闭资源。代码如下:
DatagramSocketds=new DatagramSocket();
byte[]buf=new byte[1024];
DatagramPacketdp=new DatagramPacket(buf,buf.length);
ds.receive(dp);
Stringip=dp.getAddress().getHostAdress();
Stringdata=new String(dp.getData(),0,dp.getLength());
intport=dp.getPort();//获取端口
ds.close();
以下是自己做的一个UDP的聊天工具。当然是在机器名为MrGuo和Home的两台机器在局域网内的数据传输。
以下是代码:
package myQQ;
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;
class MyQQ
{
publicstatic void main(String[] args) throwsException
{
MyQQFramemyqq=new MyQQFrame();
}
}
class MyQQFrame
{
MyQQFrame()
{
init();
}
privateFrame frame;
privateTextArea ta_sender;
privateTextArea ta_receiver;
privateButton button;
privateDatagramSocket ds_sender;
privateString talktime;
publicvoid init()
{
frame=newFrame("MyQQ");
frame.setVisible(true);
frame.setBounds(30,30,500,400);
frame.setLayout(newFlowLayout());
ta_sender=newTextArea(3,35);
ta_receiver=newTextArea(16,60);
ta_receiver.setEditable(false);
button=newButton("发送");
frame.add(ta_receiver);
frame.add(ta_sender);
frame.add(button);
try
{
ds_sender=newDatagramSocket();
}
catch(Exception e)
{
e.printStackTrace();
}
Datedate=new Date();
SimpleDateFormatsdf=new SimpleDateFormat("HH:mm");
talktime=sdf.format(date);
setEvent();
startReceive();
}
publicvoid startReceive()
{
newThread(new Runnable(){ //将接受数据作为一个线程开启一直监听端口
publicvoid run()
{
try
{
DatagramSocketds=new DatagramSocket(6777);
while(true)
{
byte[]buf=new byte[1024];
DatagramPacketdp=new DatagramPacket(buf,buf.length);
ds.receive(dp);
Stringname=dp.getAddress().getHostName();
Stringdata=new String(dp.getData(),0,dp.getLength());
ta_receiver.append(name+" "+talktime+"\r\n\t"+data+"\r\n\r\n");
}
}
catch(Exception e)
{
//System.out.println(e.toString());
}
}
}).start();
}
publicvoid setEvent()
{
button.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
try
{
byte[]buf=ta_sender.getText().getBytes();
DatagramPacketdp=newDatagramPacket(buf,buf.length,InetAddress.getByName("Home"),6777);
ds_sender.send(dp);
ta_receiver.append(InetAddress.getLocalHost().getHostName()+" "+talktime+"\r\n\t"+ta_sender.getText()+"\r\n\r\n");
ta_sender.setText("");
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
}
});
frame.addWindowListener(newWindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
}
在家里和父母在各自的房间上网,可以用自己做的工具进行交流,还是比较有成就感的哈哈。
说完UDP接下来该说TCP协议了。TCP分客户端和服务端,分别对应的是Socket和ServerSocket。客户端创建Socket服务并制定连接的主机和端口。通过Socket获取输出流对象,然后通过流对象进行数据传输。
Socket soc=new Socket(“192.168.1.3”,8888);
OutputStreamout=soc.getOutputStream();
out.write(“需要传输的数据”.getBytes())
soc.close();
而服务端需要建立服务端ServerSocket并监听一个端口,然后通过accept方法(阻塞式方法)连接过来的客户端对象,使用该对象获取该对象的读取流来读取发过来的数据。
ServerSocketss=new ServerSocket(8888);
Sockets=ss.accept();
InputStreamin=s.getInputStream();
byte[] buf=newbyte[1024];
intlen=in.read(buf);
String info=newString(buf,0,len);
以下是一个服务端和客户端建立TCP连接的例子。客户端输入一个账号,服务器会校验是否为已知用户,并返回一个信息。
import java.net.*;
import java.io.*;
class LoadThread implements Runnable//服务器每接收一个socket就开启一个此线程
{
privateSocket soc;
LoadThread(Socketsoc)
{
this.soc=soc;
}
publicvoid run()
{
Stringip=soc.getInetAddress().getHostAddress();//获取对方IP
System.out.println(ip+"connect");
try
{
BufferedReaderbr=new BufferedReader(new InputStreamReader(soc.getInputStream()));
BufferedWriterbw=new BufferedWriter(new OutputStreamWriter(soc.getOutputStream()));
Stringinfo=br.readLine();//读取信息
if(info.equals("zhangsan"))//这里可以用一个文件来记录账号,并用流来读取,这里为了简单就假设只有一个账号为zhangsan
{
bw.write("登陆成功,欢迎您"+info);//返回的信息
bw.newLine();
bw.flush();
System.out.println("zhangsan登陆");
}
else
{
bw.write(info+"不存在");
bw.newLine();
bw.flush();
System.out.println(info+"尝试登陆");//打印台上输出
}
soc.close();
}
catch(Exception e)
{
}
}
}
class Server//服务器
{
publicstatic void main(String[] args) throwsException
{
ServerSocketsersoc=new ServerSocket(9003);//监听9003端口
while(true)
{
Socketsoc=sersoc.accept();//accept为阻塞方法,一旦接受到socket,立马交给线程操作,然后开始重新接受
newThread(new LoadThread(soc)).start();
}
}
}
class Client
{
publicstatic void main(String[] args) throwsException
{
Socketsoc=new Socket("192.168.1.3",9003);//发送目的
BufferedReaderbr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriterbwOut=new BufferedWriter(new OutputStreamWriter(soc.getOutputStream()));
Stringlen=br.readLine();
bwOut.write(len);
bwOut.newLine();
bwOut.flush();
br.close();
soc.shutdownOutput();
BufferedReaderbrIn=new BufferedReader(new InputStreamReader(soc.getInputStream()));
StringlenIn=brIn.readLine();
System.out.println(lenIn);
soc.close();
}
}