------- android培训、java培训、期待与您交流!----------
网络编程的本质就是两个设备之间的数据交换。在网络编程中,发起连接请求的程序,叫做客户端;等待其他程序连接的程序叫做服务端。客户端编程可以在需要的时候开启,而服务器为了能够时刻响应客户端的连接请求需要一直开启。
1.网络参考模型:
网络参考模型包括两种:
OSI参考模型与TCP/IP参考模型
而我们所要操作的就是传输层与网络层,过程就是先将数据封包再将数据解包。
2.两种通信协议 UDP与TCP
UDP | TCP |
将所要发送的数据、数据源和目的地封装成数据包,不需要建立连接 | 建立连接,形成传输数据的通道 |
数据包的大小限制在64K内 | 在连接通道中进行大数据量传输 |
因无连接,是不可靠协议 | 通过三次握手建立连接,是可靠协议 |
不需要建立连接速度快 | 必须建立连接,效率稍低 |
3.通讯的两个端点Socket(套接字)
Socket就是网络服务提供的一种机制
通讯的两端都有Socket,网络通讯其实就是Socket间的通信
数据在两个Socket间通过IO传输
所以网络编程又称为Socket编程
4.获取IP
public static void main(String[] args) throws UnknownHostException {
//获取本地主机ip地址对象。
InetAddress ip = InetAddress.getLocalHost();
//获取其他主机的ip地址对象。
ip = InetAddress.getByName("192.168.1.110");//InetAddress.getByName("my_think");
System.out.println(ip.getHostAddress());
System.out.println(ip.getHostName());
}
5.UDP编程
Java中UDP使用的Socket是DataSocket
发送端(客户端):
public static void main(String[] args) throws IOException {
System.out.println("发送端启动......");
/*
* 创建UDP传输的发送端。
* 思路:
* 1,建立udp的socket服务。
* 2,将要发送的数据封装到数据包中。
* 3,通过udp的socket服务将数据包发送出去。
* 4,关闭socket服务。
*/
//1,udpsocket服务。使用DatagramSocket对象。
DatagramSocket ds = new DatagramSocket(8888);
//2,将要发送的数据封装到数据包中。
String str = "udp传输演示:哥们来了!";
//使用DatagramPacket将数据封装到的该对象包中。
byte[] buf = str.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);
//3,通过udp的socket服务将数据包发送出去。使用send方法。
ds.send(dp);
//4,关闭资源。
ds.close();
}
}
接收端(服务端)
//1,建立udp socket服务。
DatagramSocket ds = new DatagramSocket(10000);
//2,创建数据包。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3,使用接收方法将数据存储到数据包中。
ds.receive(dp);//阻塞式的。
//4,通过数据包对象的方法,解析其中的数据,比如,地址,端口,数据内容。
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+":"+port+":"+text);
//5,关闭资源。
ds.close();
6.TCP编程
客户端通过IP寻找到服务器电脑,通过端口找到服务器程序,所以服务器程序要监听某个端口。
客户端:
//创建客户端socket服务。建议该对象一创建就明确目的地。要连接的主机。
Socket socket = new Socket("192.168.1.100",10002);
//获取socket流中的输出流。建立的通道就是Socket流, Socket连接建立好之后,底层就拥有了输入输出流
OutputStream out = socket.getOutputStream();
//使用输出流将指定的数据写出去。也就是将信息写入到Socket流的输出流。
out.write("tcp演示:哥们又来了!".getBytes());
//关闭资源。
socket.close();
服务器:
ServerSocket不建立流,但他可以通过accept方法获取客户端发过来的Socket对象,从而利用Socket对象输入流的接受客户端发过来的数据,或者利用输出流给客户端发送数据。
//1创建服务端对象。通过ServerSocket对象。
//服务端必须对外提供一个端口,否则客户端无法连接。
ServerSocket ss = new ServerSocket(10002);
//2,获取连接过来的客户端对象。
Socket s = ss.accept();//阻塞式.
String ip = s.getInetAddress().getHostAddress();
//3,通过socket对象获取输入流,要读取客户端发来的数据
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(ip+":"+text);
s.close();
ss.close();
上面的代码只是单向通信的,下面我们举一个双向通信的例子:
客户端为服务端发送txt文件,服务器给客户端反馈信息:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class TCPSend {
public static void main(String[] args)throws Exception
{
Socket s = new Socket("127.0.0.1",65530);
//指定客户端数据源
BufferedReader brs = new BufferedReader(new FileReader("C://111.txt"));
//获得Socket输出流
PrintWriter pws = new PrintWriter(s.getOutputStream(),true);
//将源文件写入Socket输出流
String line;
while( (line = brs.readLine()) != null)
{
pws.println(line);
}
//告诉服务端写完了
s.shutdownOutput();
//获得从服务端发回Socket输入流(接受的都是输入流)
BufferedReader brss = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = brss.readLine();
System.out.println(str);
//关闭资源
brss.close();
brs.close();
s.close();
}
}
<p>import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;</p><p>
public class TCPRec {</p><p> public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(65530);
Socket s = ss.accept();
//获得和谁连接了
System.out.println(s.getInetAddress().getHostAddress()+"连接上来了");
//接受客户端发送的数据
BufferedReader br = new BufferedReader( new InputStreamReader(s.getInputStream()));
PrintWriter pw = new PrintWriter(new FileWriter("c://22t.txt"),true);
String line ;
while((line = br.readLine()) != null)
{
pw.println(line);
}
//给客户端反馈信息
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write("上传成功");
bw.flush();
//关闭资源
br.close();
s.close();
ss.close();
pw.close();
}
总结:
UDP使用DatagramSocket,既可以发送也可以接受,使用send和receive方法,他不必建立连接,因为客户端在装包时就已经将要发送的地址以及所使用的端口号就装进了包中,服务端要先建立一个包以便间即受到的信息装入包中,然后再拆包。
TCP的客户端使用Socket,它只能使用客户端,必须指明服务端的地址和发送的端口号,一旦建立成功就会形成Socket流也就是通道,它包含输入输出流,记住发送使用输出流,接受使用输入流。
TCP的服务端使用ServerSocket,他只能用于服务端,它不具有流,但它具有接受客户端发送过来的Socket对象的方法,所以服务端先获得Socket'对象然后再利用他的输入流读取发过来的信息。
需要额外注意的是,TCP客户端将数据写入输出流完成时应该给一个结束标记shutdowmOutput().