套接字Socket:
TCP通信与UDP通信需要用到Socket:为了方便开发网络应用程序,美国伯克利大学在Unix上实现的一种应用程序访问网络的通信协议Socket,Socket的出现使程序员可以很方便的访问TCP/IP。
使用TCP进行通信:
服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户端到端口的连接请求。
package server;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
//声明服务器的端口号
ServerSocket serverSocket = new ServerSocket(1111);
//等待接收一个socket
Socket socket = serverSocket.accept();
//根据socket获得输入流
InputStream inputStream = socket.getInputStream();
//创建输出流
FileOutputStream fileOutputStream = new FileOutputStream("D:\\1.png");
byte[] car = new byte[1024];
int length = 0;
//将接收的输入流写入输出流,即写入本地文件中
while((length = inputStream.read(car)) != -1) {
fileOutputStream.write(car);
}
//刷新缓冲区
fileOutputStream.flush();
//关闭资源
fileOutputStream.close();
inputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端程序根据服务器程序所在的主机名和端口发出连接请求。
package client;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
try {
//创建套接字对象socket并封装ip与port
Socket socket = new Socket("127.0.0.1", 1111);
//根据创建的socket对象获得一个输出流
OutputStream outputStream = socket.getOutputStream();
//创建输入流,即要从本地发送给服务器的文件输入流
FileInputStream fileInputStream = new FileInputStream("D:\\icon.png");
byte[] car = new byte[1024];
int length = 0;
//将本地文件以IO流的方法发送给服务器
while((length = fileInputStream.read(car)) != -1) {
outputStream.write(car, 0, length);
}
//刷新缓冲区
outputStream.flush();
//关闭资源
fileInputStream.close();
fileInputStream.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
测试:
- 先运行服务器端程序,服务器端程序会处于等待连接状态;
- 再运行客户端程序,确认连接后开始发送文件;
- 发送完毕后,服务器与客户端确认断开连接。
- 两个程序结束。
- 本地磁盘中已经收到客户端发送的文件:
使用UDP进行通信:
UDP是用户数据报协议,基于UDP的Socket编程是一种非连接的Socket通信,它提供的是无连接、不可靠信息传送服务。
- DatagramSocket:用来发送和接收数据包的套接字
- DatagramPacket :表示数据包
客户端步骤:
- 创建数据Socket,指定一个服务端端口号。
- 提供一个byte数组用于数据存储。
- 调用DatagramPacket的receive() 方法进行数据的接收;
- 调用DatagramPacket的getData()方法得到byte数组的数据;
- 释放资源。
package server;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Server {
public static void main(String[] args) {
try {
DatagramSocket socket = new DatagramSocket(1111);
byte[] car = new byte[1024];
DatagramPacket packet = new DatagramPacket(car, car.length);
socket.receive(packet);
int length = packet.getLength();
System.out.println(new String(car, 0, length));
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
步骤:
- 创建数据Socket,指定一个客户端端口号。
- 提供一个存储了所发送数据的byte数组,提供服务端的IP地址和端口号。
- 调用DatagramPacket的send()方法进行数据的发送;
- 释放资源。
package client;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class Client {
public static void main(String[] args) {
try {
DatagramSocket socket = new DatagramSocket(2222);
byte[] car = "来自火星的问候".getBytes();
InetSocketAddress address = new InetSocketAddress("127.0.0.1",1111);
DatagramPacket packet = new DatagramPacket(car, car.length, address);
socket.send(packet);
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
测试:
- 先运行服务器端程序,此时程序等待接收数据;
- 再运行客户端程序,发送完毕程序结束;
- 服务器端接收到数据后,对接收的数据进行操作,完事儿后结束程序;
- 控制台结果如下:
TCP与UDP区别:
1、TCP面向连接,发送数据前要先建立连接;UDP是无连接的,发送数据前不需要建立连接;
TCP通信可看作打电话:
- 甲(拨了个号码):喂,是乙吗?
- 乙:哎,您哪位?
- 甲:我是甲,我给你说点事儿,你能听到吗?
- 乙:哦,我能听见,你说吧。
- 甲:那我说了啊?
- 乙:你说吧。
- (连接建立了,接下来传输数据…)
UDP通信可看做村里的喇叭:
- 村长:喂喂喂!狗蛋听见广播到队部来下。
- …
- (狗蛋到底听到没,或是听清没,村长是不知道的)
2、TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,不保证可靠交付;
3、UDP有较好的实时性,效率比TCP高,适用于对高速传输和实时性较高的通信或广播通信;
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信;
- TCP通信类似于打电话,接通了,确认身份后,开始通话;
- UDP通信类似于村喇叭,很多村民都能听到。