/**
* UDP通讯协议的特点:
* 1.将数据及其原源和目的封装为数据包,不需要建立连接
* 2.每个数据包大小限制在64k
* 3.因为无连接,所以不可靠
* 4.因为不需要建立连接,所以速度快
* 5.UDP通讯是不分服务端与客户端的,只分发送端与接收端
* 如:人说话、CS等
*
* TCP通讯协议的特点:
* 1.面向连接,有特有的通道,基于IO流进行数据传输
* 2.在连接中传输大数据量
* 3.通过三次握手机制连接,可靠协议
* 4.通信前必须建立连接,效率稍低
* 5.TCP是区分客户端和服务端的
* 如:打电话、文件的传送
*
* TCP协议下的Socket
* Socket(客户端) TCP的客户端一旦启动马上要与服务端进行连接
* ServerSocket(服务端类)
*
* 为什么ServerSocket不设计一个getInputStream和getOutputStream呢?
* */
一、使用TCP实现服务端与客户端之间的连接
服务端代码:
package com.shuhuadream.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) {
try {
//创建服务端套接字对象
ServerSocket serverSocket = new ServerSocket(9000);
//接收服务端的连接
Socket socket = serverSocket.accept();
System.out.println("有一个客户端连接成功了:"+socket.getInetAddress());
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
os.write("芝麻开门".getBytes());
os.flush();
byte[] buf = new byte[1024];
int hasRead = 0;
while((hasRead = is.read(buf))!=-1){
System.out.println(new String(buf,0,hasRead));
}
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码:
package com.shuhuadream.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class MyClient {
public static void main(String[] args) {
//1.创建客户端对象,在对象中指定与其连接的服务器IP地址和端口号
try {
Socket socket = new Socket(InetAddress.getByName("192.168.201.1"),9000);
//2.获取Socket的输入流对象、输出流对象
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
byte[] buf = new byte[1024];
int hasRead = 0;
while((hasRead=is.read(buf))!=-1){
System.out.println(new String(buf,0,hasRead));
os.write("服务端你好,初次见面,请多指教".getBytes());
os.flush();
}
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
实验效果图:
二、实现服务端可供多个客户端下载图片的功能
服务端代码:
package com.shuhuadream.tcp;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
//提供下载文件线程
class DownloadServerThread extends Thread{
private Socket socket; //客户端套接字对象
private File srcFile; //需要被下载的文件对象
public DownloadServerThread(Socket socket, File srcFile) {
super();
this.socket = socket;
this.srcFile = srcFile;
}
public void run() {
FileInputStream fis = null;
OutputStream os = null;
try {
fis = new FileInputStream(srcFile);//建立文件输入流
os = socket.getOutputStream();//获取客户端socket输出流
byte[] buf = new byte[1024];//建立缓冲字节数组
int hasRead = 0;
while((hasRead = fis.read(buf))!=-1){//读取传输文件
os.write(buf, 0, hasRead);//写入客户端文件数据
}
os.flush();//刷新
} catch (IOException e) {
e.printStackTrace();
} finally{
FileUtils.closeIO(new Closeable[]{fis,os});//关闭IO
}
}
}
//搭建可供多个客户端下载文件服务端
public class DownloadServer{
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8899);
System.out.println("服务端启动了......");
File srcFile = new File("d:\\demo\\car.jpg");
while(true){
//接受客户端连接,获取Socket
Socket socket = serverSocket.accept();
System.out.println("已经连接到的客户端有:"+socket.getInetAddress().getHostAddress());
//创建下载线程
DownloadServerThread thread = new DownloadServerThread(socket,srcFile);
//开启线程
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码:
package com.shuhuadream.tcp;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
//客户端
public class DownloadClient {
public static void main(String[] args) {
InputStream is = null;
FileOutputStream fos =null;
try {
//创建客户端对象,在对象中指定与其连接的服务器IP地址和端口号
Socket socket = new Socket(InetAddress.getByName("10.41.151.63"),8899);
//获取Socket输入流对象
is = socket.getInputStream();
//创建文件输出流通道
fos = new FileOutputStream(new File("car.jpg"));
//创建缓冲数组
byte[] buf = new byte[1024];
int hasRead = 0;
//读取服务端传来数据并写入到指定文件路径
while((hasRead = is.read(buf))!=-1){
fos.write(buf, 0, hasRead);
}
//刷新
fos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
关闭流工具类代码:
package com.shuhuadream.tcp;
import java.io.Closeable;
import java.io.IOException;
//关闭IO的工具类
public class FileUtils {
public static void closeIO(Closeable...ios){
for (Closeable io : ios) {
if(io!=null){
try {
io.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
三、实现服务端能够接收多个客户端发送图片并进行保存
服务端代码:
package com.shuhuadream.tcp2;
import java.io.Closeable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import com.shuhuadream.tcp.FileUtils;
//接收客户端发来文件线程
class UploadServerThread extends Thread{
private Socket socket;
public UploadServerThread(Socket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
InputStream is = null;
FileOutputStream fos = null;
try {
//获取socket输入流对象
is = socket.getInputStream();
//创建文件输出流对象
fos = new FileOutputStream(System.currentTimeMillis()+".jpg");
//建立缓冲数组
byte[] buf = new byte[1024];
int hasRead = 0;
//读取客户端传来数据并写入到本地
while((hasRead = is.read(buf))!=-1){
fos.write(buf, 0, hasRead);
}
//刷新
fos.flush();
System.out.println("文件传输成功!");
} catch (IOException e) {
e.printStackTrace();
} finally{
//关闭资源
FileUtils.closeIO(new Closeable[]{is,fos});
}
}
}
public class UploadServer {
public static void main(String[] args) {
try {
//创建服务器套接字对象
ServerSocket serverSocket = new ServerSocket(8887);
System.out.println("服务器启动了......");
while(true){
//接受客户端连接,生成Socket
Socket socket = serverSocket.accept();
//创建下载线程
UploadServerThread thread = new UploadServerThread(socket);
//开启线程
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码:
package com.shuhuadream.tcp2;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import com.shuhuadream.tcp.FileUtils;
//客户端
public class UploadClient {
public static void main(String[] args) {
FileInputStream fis = null;
OutputStream os = null;
try {
fis = new FileInputStream("car.jpg");
Socket socket = new Socket(InetAddress.getByName("10.41.151.63"),8888);
os = socket.getOutputStream();
byte[] buf = new byte[1024];
int hasRead = 0;
while((hasRead = fis.read(buf))!=-1){
os.write(buf, 0, hasRead);
}
os.flush();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
FileUtils.closeIO(new Closeable[]{os,fis});
}
}
}
实验结果: