概念
* 传输协议:TCP UDP
* TCP:一种面向连接的、可靠的、基于字节流的运输层通信协议,特点:
* 面向连接;点到点的通信;高可靠性;占用系统资源多、效率低。
* 就像打电话:拨通、说喂、确认。这就是三次握手。
*UDP:一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,特点:
* 非面向连接,传输不可靠,可能丢失;发送不管对方是否准备好,接收方
* 收到也不确认;可以广播发送;非常简单的协议,开销小、效率高。
* 就像寄包裹,不知道什么时候送到,可能会丢失。
*开发的网络应用程序位于应用层,TCP和UDP属于传输层协议,在应用层如何使用
* 传输层的服务呢?在应用层和传输层之间,则是使用套接字来进行分离。
*套接字socket:就像是传输层为应用层开的一个小口,应用层通过这个小口向远程
* 发送数据或者接受远程发来的数据,那么数据进出这个小口不知道也不用关心是
* 怎么传输的,这是网络其他层次的工作。
* 基于TCP协议的socket编程:通信双方需要建立连接,连接建立时双方存在主次之分。
* 基于UDP协议的scoket编程:通信双方不需要建立连接,双方平等,比如QQ聊天。
TCP编程基本步骤:
* TCP编程:1.使用基于TCP协议的Socket网络编程实现。
* 2.TCP协议基于请求-响应模式。
* 3.在网络通讯中,第一次主动发起通讯的程序被称为
* 客户端(client)程序;第一次通讯中等待连接的程序
* 被称为服务器(server)程序
* 4.利用IO流实现数据的传输
TCP客户端:
* 客户端:
* 1.创建socket(String host,int port)对象 建立连接
* 2.操作:输入输出流
* 3.关闭流和socket对象
public class TestTcpSocket {
public static void main(String[] args) throws IOException {
System.out.println("----客户端------");
socketString();
}
public static void socketString() throws IOException{
//1
Socket socket = new Socket("localhost",8888);
//2
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
String data = "nihao";
dos.writeUTF(data);
//3
dos.flush();
dos.close();
socket.close();
}
}
TCP服务端:
* 服务端:
* 1.创建serverSocket(int port)对象
* 2.阻塞、等待连接的建立 accept
* 3.操作:输入输出流
* 4.关闭流和socket对象
public class TestTcpServer {
public static void main(String[] args) throws IOException{
System.out.println("----服务端------");
serverString();
}
public static void serverString() throws IOException{
//1
ServerSocket server = new ServerSocket(8888);
//2
Socket socket = server.accept();
//用浏览器访问本机就会建立联系,输出下面这句话
System.out.println("一个客户端建立了连接");
//3
DataInputStream dis = new DataInputStream(socket.getInputStream());
String data = dis.readUTF();
System.out.println(data);
//4
dis.close();
socket.close();
server.close();//服务器一般是不会关的
}
}
先启动服务端,再启动客户端,注意,两个端口要一样,不然会报错,端口不一样,客户端就找不到服务端了。
UDP编程基本步骤:
* UDP编程:1.使用基于UDP协议的scoket网络编程实现。
* 2.数据被封装成数据包,发送方将数据包发送到网络中,
* 数据包在网络中寻找目的地。
* 3.底层实现的是字节,多个包就是字节数组,所以不需要利用IO流实现数据的传输。
* DatagramSocket:用于发送或接受数据包的套接字。
* DatagramPacket:数据包
UDP发送端:
* 发送端:
* 1.使用 DatagramSocket 创建发送端 指定端口
* 2.准备数据 转成字节数组
* 3.封装成DatagramPacket 数据包
* 4.发送数据包 send方法
* 5.释放资源
public class TestUdpClient {
public static void main(String[] args) throws Exception {
System.out.println("发送方启动中。。。。。");
clientString();
}
public static void clientString() throws Exception {
DatagramSocket client = new DatagramSocket(8888);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String data = "数据包来了";
byte[] datas = data.getBytes();
DatagramPacket packet = //下面的第四个参数是创建本机的,9999要和接收端那指定的端口一致,不然会丢失数据包
new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 9999));
client.send(packet);
client.close();
}
}
UDP接收端:
* UDP接收端:
* 1.使用 DatagramSocket 创建接收端 指定端口
* 2.准备容器 封装成DatagramPacket 数据包
* 3.阻塞式接受数据包 receive方法
* 4.分析数据 byte[] getData()
* getLength()
* 5.释放资源
public class TestUdpServer {
public static void main(String[] args) throws Exception {
System.out.println("接收方启动中");
serverString();
}
public static void serverString() throws Exception {
// Address already in use: Cannot bind 这个错误是由于同一个机子同一协议下端口冲突
DatagramSocket server = new DatagramSocket(9999);
byte[] container = new byte[1024*60];//最多只能操作1024*60的数据,太大会报错
DatagramPacket packet = new DatagramPacket(container,0,container.length);
server.receive(packet);
byte[] datas = packet.getData();
System.out.println(new String(datas,0,datas.length));
server.close();
}
}
先执行接收端,在执行发送端,注意,1.使用 DatagramSocket创建的时候,两个端口不能一样,不然会冲突,会报Address already in use: Cannot bind这个错误,这是由于同一机子同一协议下端口冲突;2.发送端封装成数据包时写的端口要和接收端的端口一样,不然会丢失。