C/S结构
B/S结构
网络通信协议:
Ipv4是4个字节,就是4*8=32位,ipv6是16个字节,不是6,就有16*8=128位
demo1代码:
客户端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
//TCP通信的客户端
public class TCPClient {
public static void main(String[] args) throws IOException {
//创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号
Socket socket = new Socket("127.0.0.1",8888);
//使用socket对象中的方法getoutputstream获取获取网络字节输出流对象
OutputStream os = socket.getOutputStream();
//使用刚获取到的字节输出流outputstream对象中的方法write,给服务器发送数据
os.write("发送数据".getBytes());
//使用Socket对象中的方法getInputStream获取网络字节输入流InputStream对象
InputStream is = socket.getInputStream();
//使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes));
socket.close();
}
}
服务器:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
//TCP通信中的服务器端
public static void main(String[] args) throws IOException {
//服务器端不许明确那个客户端请求了服务器
//所以可以使用accept方法获取到请求的客户端对象Socket
//Scoket 的accept()方法监听并接受到此套接字的连接
/**
* 服务器实现步骤:
* 1、创建服务器对象并向系统要指定的端口号
* 2、使用Serversocket方法中的accept,获取到请求的客户端对象Socket
* 3、使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream
* 4、使用网络字节输入流中的InputStream对象中的方法read,读取客户端发送的数据
* 5、使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
* 6、使用网络字节输出流OutputStream中的方法write,给客户端回写数据
* 7、释放资源Socket,ServerSocket
* */
ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept();
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes));
OutputStream os = socket.getOutputStream();
os.write("收到".getBytes());
}
}
demo2实现文件上传,有缺陷:单线程,只能传一次,服务器就关了
客户端:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* 数据源:c://1.txt
* 目的地:服务器
*
* 实现步骤
* 1、创建一个本地字节输入流InputStream对象,构造方法中绑定要读取的数据
* 2、创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
* 3、使用Socket对象中的方法getOutPutStream,获取网络字节输出流OutputStream对象
* 4、使用本地字节输入流FileInputStream对象中的read方法,读取本地文件
* 5、使用网络字节输出流OutputStream对象中的write方法,把读取到的文件上传到服务器
*
* 6、上传完文件,给服务器一个结束标记,不写结束标记,服务器的读入操作不会结束
* 6、使用Socket中的getInputStream方法,获取网络字节输入流InputStream对象
* 7、使用网络字节输入流InputStream对象中的read方法读取服务器回写的数据
* 8、释放资源FileInputStream,Socket
* */
public class FileuploadTCPClient {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("d:\\1.txt");
Socket socket = new Socket("127.0.0.1",8888);
OutputStream os = socket.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while((len = fileInputStream.read(bytes))!=-1){
os.write(bytes,0,len);
}
//上传完文件,给服务器一个结束标记
socket.shutdownOutput();
System.out.println("byte"+bytes);
InputStream inputStream = socket.getInputStream();
while((len=inputStream.read(bytes))!=-1){
System.out.println(new String(bytes) );
}
socket.close();
fileInputStream.close();
}
}
服务器:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 文件上传的服务器端:读取客户端上传的文件并写到服务器的硬盘中,给客户端回写“上传成功"
* 数据源:客户端上传的文件
* 目的地:服务器的硬盘D:\\1.png
*
* 实现步骤:
* 1、创建服务器ServerSocket对象,和系统要指定的端口号
* 2、使用ServerSocket对象中的方法accept,获取客户端的Socket对象
* 3、使用Socket对象中的getInputStream,获取网路字节输入流InputStream对象
* 4、判断文件夹“D:\\”是否存在,不存在就创建
* 5、创建一个本地字节输出流FileOutputStream,构造方法中绑定输出的目的地
* 6、使用InputStream对象的read方法,读取客户端上传的文件
* 7、使用本地字节输出流FileOutputStream对象中的write方法,把读到的文件保存到服务器的硬盘上
* 8、使用Socket对象中的getOutputStream方法,获取网络字节输出流对象OutputStream对象
* 9、使用OutputStream对象的write方法,给客户端回写“上传成功”
* 10、释放资源,FilOutputStream、Socket、ServerSocket
*/
public class FileUploadTCPServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
File file = new File("d:\\to");
if(!file.exists()){
file.mkdirs();
}
FileOutputStream fileOutputStream = new FileOutputStream(file+"\\"+"1.txt");
int len = 0;
System.out.println("1");
byte[] bytes = new byte[1024];
while ((len = is.read(bytes))!=-1){
System.out.println("sdsd");
fileOutputStream.write(bytes,0,len);
}
System.out.println("2");
socket.getOutputStream().write("上传成功".getBytes());
socket.shutdownOutput();
System.out.println("3");
fileOutputStream.close();
socket.close();
serverSocket.close();
}
}
demo3 改进文件上传的案例,可以上传多次,服务器一直监听socket,并使用多线程加快速度
客户端:
package uploadfile;
import javax.sound.midi.Soundbank;
import java.io.*;
import java.net.Socket;
public class FileuploadTCPClient {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("d:\\1.txt");
Socket socket = new Socket("127.0.0.1",8888);
OutputStream os = socket.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while((len = fileInputStream.read(bytes))!=-1){
os.write(bytes,0,len);
}
System.out.println("2");
//上传完文件,给服务器一个结束标记
socket.shutdownOutput();
System.out.println("byte"+bytes);
InputStream inputStream = socket.getInputStream();
while((len=inputStream.read(bytes))!=-1){
System.out.println(new String(bytes) );
}
System.out.println("3");
socket.close();
fileInputStream.close();
}
}
服务器:
package uploadfile;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
public class FileUploadTCPServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
//使用死循环一直监听,但是效率低
while(true){
Socket socket = serverSocket.accept();
//使用多线程提高程序的效率
//有一个客户端上传文件,就开启一个线程,完成文件的上传
new Thread(new Runnable() {
//重写了run方法,原来的方法public abstract void run();中没有声明抛出异常,自雷冲洗方法时也不能声明抛出,只能使用try catch
@Override
public void run() {
try{
InputStream is = socket.getInputStream();
File file = new File("d:\\to");
if(!file.exists()){
file.mkdirs();
}
//自定义命名规则,防止名称被覆盖
//规则:域名+毫秒值+随机数
String fileName = "ghy"+System.currentTimeMillis()+new Random().nextInt(9999)+".txt";
FileOutputStream fileOutputStream = new FileOutputStream(file+"\\"+fileName);
int len = 0;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
socket.getOutputStream().write("上传成功".getBytes());
System.out.println("上传成功");
socket.shutdownOutput();
fileOutputStream.close();
socket.close();
}catch ( IOException e){
System.out.println(e);
}
}
}).start();
}
}
}