网络编程: 通过使用套接字来达到进程间通信目的的编程就是网络编程
网络通信三要素:IP,端口号,传输协议。
IP:主机的具体地址,也就是相当于生活中的楼号某某街道某某小区几号楼几单元这样的一个地址。
端口号:网络通信中通过IP地址找到了主机,而端口号就是这个主机上所运行的程序一个编号,就相当于比如1001房间,在主机中所运行的每一个程序都有一个服务的端口号。
网络通信的两种模型:
在发送数据的时候通过从上到下应用层->表示层->..->物理层进行数据的封装,在接收数据时是由下往上物理层->数据连接层->...->应用层这样的方式将数据拆包出来。
常见的两种通讯协议模式:
1.UDP协议:通过将数据以及源和目的数据封装进数据包中,不需要建立链接就可以传输数据,不过这种方式有局限性,并且容易丢数据,但是这种方式的传输速度快,
日常生活中的,直接就是利用UDP这种模式。
2.TCP/IP协议:需要建立三次链接形成传输数据的通道,是一种可靠的协议,传输的效率比较低,日常中打电话就是这种模式。这里的三次链接就好比我发送了一个请求等待对方的回应,当对方接收到了我的请求以后返回了一个信息说收到请求了,这时就再次反馈一个信息给接收方表示知道你收到请求了,这样TCP/IP协议链接就建立好了。
无论是UDP还是TCP都需要使用Socket才能使数据进行交互,Socket是为网络服务提供的一种机制,在通讯的两端都需要具有Socket,数据在两个Socket之间通过IO传输就形成数据的交互。
UDP如何使用Socket进行数据的传输:
1,通过DatagramSocket类建立UDPSocket 服务。
2,建立数据包将要传输的数据封装。这里就会使用到DatagramPacket类,将数据封装。
3,发送数据
4,关闭Socket资源。
package com.leo.netpro;
import java.io.IOException;
import java.net.*;
public class UdpDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
DatagramSocket ds = null;
try {
//创建UDP服务
ds = new DatagramSocket();
//确定数据封装数据
byte[] data = "Send UDP Data".getBytes();
DatagramPacket dp = new DatagramPacket(data, data.length,InetAddress.getByName("192.168.1.104"),10000);
ds.send(dp);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
//关闭资源
if(ds!=null)
ds.close();
}
}
}
上面这段代码就建立好了一个发送数据的一端,发送端建立好了就需要建立一个接收数据的端点接收端同样需要
1,建立UdpSocket服务。通常会监听一个端口,接收网络应用程序定义一个数字标识。
方便明确哪些数据过来应该此程序处理。
2,定义数据包,存储接收到的字节数据。数据包对象中有更多的功能可以提取字节数据中的不同数据信息。
3,通过Socket服务的receive方法将收到的数据存入一定义的数据包中。
4,通过数据包对象特有宫恩那个取出数据,打印。
5,关闭资源。
package com.leo.netpro;
import java.io.IOException;
import java.net.*;
public class UdpReceive {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建udp socket,建立端点
DatagramSocket ds = null;
try {
ds = new DatagramSocket(10000);
while(true)
{
//定义数据包,存储数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
//接收数据存入数据包。
ds.receive(dp);
//通过数据包方法获取数据
String ip = dp.getAddress().getHostAddress();//获取数据来源地址
String data = new String(dp.getData(),0,dp.getLength());
System.out.println("IP:"+ip+"=======data:"+data);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
if(ds!=null)
ds.close();
}
}
}
这样一一个UDP模式传输就完成了。
TCP传输:需要建立客户端(Socket)和服务端对象(ServerSocket)
客户端:
1.建立Socket服务端点
2.获取客户端数据。
3.通过Socket输出流将数据发送给服务端。
4.读取服务端反馈的信息。
5.关闭资源。
package com.leo.netpro;
import java.io.*;
import java.net.*;
public class TcpClient {
public static void main(String[] args) {
Socket s = null;
try {
//创建客户端Socket服务,指定主机和端口
s = new Socket("192.168.1.104",3020);
//获取Socket流中的输出流
OutputStream outs = s.getOutputStream();
outs.write("hello server".getBytes());
} catch (UnknownHostException e) {
throw new RuntimeException("获取主机地址失败");
} catch (IOException e) {
throw new RuntimeException("流中数据不能为空");
}finally{
try {
if(s!=null)
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
这样一个简单的Tcp客户端就建立成功,接下来建立服务器端,服务端跟客户端大同小
1.需要建立服务端点,
2.定义Socket读取流接收客户端发送过来的数据,
3.定义Socket输出流,反馈信息给客户端。
package com.leo.netpro;
import java.io.*;
import java.net.*;
public class TcpServer {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//建立服务端Socket服务,监听端口
ServerSocket ss = new ServerSocket(3020);
//通过accept方法获取连接过来的客户端对象
Socket s = ss.accept();
//获取客户端发送过来的数据
InputStream in =s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
if(len>0)
System.out.println(new String(buf,0,len));
OutputStream out = s.getOutputStream();
out.write("hello Client".getBytes());
}
}
通过客户端跟服务端的交互就可以完成一个TCP传输。