java中
Socket类
importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.Socket;public classClient {public static void main(String[] args) throwsIOException {//创建socket,指定服务器的ip 和端口
Socket socket = new Socket("127.0.0.1",8888);//从socket里面获取字节输出流,准备给服务器发送数据
OutputStream ops =socket.getOutputStream();
ops.write("你好,全植强的服务器".getBytes());//没有服务器会抛出异常:thread "main" java.net.ConnectException: Connection refused: connect//获取字节输入流,接受来自服务器的回馈数据
InputStream ips =socket.getInputStream();byte[] bytes = new byte[1024];//创建接受字节数组,数组长度初定为
int len = ips.read(bytes);//将数据读入数组,返回数组的长度
System.out.println(new String(bytes,0,len));//输出数据
socket.close();
}
}
ServerSocket类
importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.ServerSocket;importjava.net.Socket;public classServer {public static void main(String[] args) throwsIOException {//创建ServerSocket 指定端口号,不指定就有系统随机安排!!
ServerSocket server = new ServerSocket(8888);//监听获取客户端的socket
Socket socket=server.accept();//从获取到客户端的socket创建字节输入流,准备读取客户端发来的数据
InputStream ips =socket.getInputStream();byte[] bytes = new byte[1024];int len = ips.read(bytes);//将数据读入数组,返回数据的长度
System.out.println(new String(bytes,0,len));
OutputStream ops=socket.getOutputStream();
ops.write("收到小弟".getBytes());
socket.close();
server.close();
}
}
TCP文件上传是咧
FileClient
/*文件上传的客服端,读取本地文件,上传到服务器,读取服务器回写的数据
数据源:Snipaste_2020-06-25_23-37-15.png
目的地:服务器*/
public classTcpSocketFileClient {public static void main(String[] args) throwsIOException {
FileInputStream fis= new FileInputStream("Snipaste_2020-06-25_23-37-15.png");
Socket socket= new Socket("127.0.0.1",8888);
OutputStream os=socket.getOutputStream();int len = 0;byte[] bytes = new byte[1024];/*@return the total number of bytes read into the buffer, or
* -1
if there is no more data because the end of
* the file has been reached.*/
while ((len = fis.read(bytes)) != -1){
System.out.println(len);
os.write(bytes,0,len);
}
InputStream ips=socket.getInputStream();while ((len = ips.read(bytes)) != -1){
System.out.println(new String(bytes,0,len));
}
fis.close();
socket.close();
}
}
FileServer::
importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.net.ServerSocket;importjava.net.Socket;public classTcpSocketFileServer {public static void main(String[] args) throwsIOException {//创建服务器socket指定端口号
ServerSocket server = new ServerSocket(8888);//监听客户端,获取socket
Socket socket =server.accept();//获取socket中的字节输入流,读取客户端传进来的数据
InputStream ips =socket.getInputStream();//判断文件对象是否存在
File file = new File("d:\\upload");if(!file.exists()){
file.mkdir();
}//获取本地文件输出字节流,准备将从客户端获取到的文件写出到本地磁盘中
FileOutputStream fops = new FileOutputStream(file+"\\up.png");//读取客户端发来的输入字节流
int len = 0;byte[] bytes = new byte[1024];while ((len = ips.read(bytes))!= -1){//网本地输出字节流写入客户端的数据
fops.write(bytes,0,len);
}//使用socket中的字节输出字节流往客户端输出数据
socket.getOutputStream().write("done".getBytes());
fops.close();
socket.close();
server.close();
}
}
运行服务器再运行客户端最后发现:
当时两个程序都没有停止下来,为什么:
解决方法;
客户端加入:
结果,两个程序都结束,client也收到结果:
优化服务端
/*优化,自定义一个文件的命名规则,防止同盟的文件被覆盖掉
规则:域名+毫秒数+随机数*/String filename= "\\better.quan"+System.currentTimeMillis()+new Random().nextInt(787878)+".png";
FileOutputStream fops= new FileOutputStream(file+filename);//读取客户端发来的输入字节流
int len = 0;byte[] bytes = new byte[1024];while ((len = ips.read(bytes))!= -1){//网本地输出字节流写入客户端的数据
fops.write(bytes,0,len);
}
结果:
优化2:让服务器不停下,持续监听,客户端就能不断上传文件:
/*让服务器一直处于监听状态(死循环accept方法)
有一个客户端上传文件,就保存一个文件*/
while (true){
Socket socket=server.accept();//获取socket中的字节输入流,读取客户端传进来的数据
InputStream ips =socket.getInputStream();//判断文件对象是否存在
File file = new File("d:\\upload");if(!file.exists()){
file.mkdir();
}//获取本地文件输出字节流,准备将从客户端获取到的文件写出到本地磁盘中
/*优化,自定义一个文件的命名规则,防止同盟的文件被覆盖掉
规则:域名+毫秒数+随机数*/String filename= "\\better.quan"+System.currentTimeMillis()+new Random().nextInt(787878)+".png";
FileOutputStream fops= new FileOutputStream(file+filename);//读取客户端发来的输入字节流
int len = 0;byte[] bytes = new byte[1024];while ((len = ips.read(bytes))!= -1){//网本地输出字节流写入客户端的数据
fops.write(bytes,0,len);
}//使用socket中的字节输出字节流往客户端输出数据
socket.getOutputStream().write("done".getBytes());
fops.close();
socket.close();
}//不用关闭服务器//server.close();
多次启动客户端
优化三:提高效率,利用多线程
来一个客户端上传文件请求,开启一个线程去处理
public classTcpSocketFileServer {public static void main(String[] args) throwsIOException {//创建服务器socket指定端口号
ServerSocket server = new ServerSocket(8888);//监听客户端,获取socket
/*让服务器一直处于监听状态(死循环accept方法)
有一个客户端上传文件,就保存一个文件*/
while (true) {
Socket socket=server.accept();//获取socket中的字节输入流,读取客户端传进来的数据
/*使用多线程,提高程序的效率
有一个客户端上传文件,就开启一个线程,完成文件的上传*/
new Thread(newRunnable() {
@Overridepublic voidrun() {try {//由于接口类当中没有throw异常,使用try catch
InputStream ips =socket.getInputStream();//判断文件对象是否存在
File file = new File("d:\\upload");if (!file.exists()) {
file.mkdir();
}//获取本地文件输出字节流,准备将从客户端获取到的文件写出到本地磁盘中
/*优化,自定义一个文件的命名规则,防止同盟的文件被覆盖掉
规则:域名+毫秒数+随机数*/String filename= "\\better.quan" + System.currentTimeMillis() + new Random().nextInt(787878) + ".png";
FileOutputStream fops= new FileOutputStream(file +filename);//读取客户端发来的输入字节流
int len = 0;byte[] bytes = new byte[1024];while ((len = ips.read(bytes)) != -1) {//网本地输出字节流写入客户端的数据
fops.write(bytes, 0, len);
}//使用socket中的字节输出字节流往客户端输出数据
socket.getOutputStream().write("done".getBytes());
fops.close();
socket.close();
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
}
}).start();//不用关闭服务器//server.close();
}
}
}
模拟B\S服务器
//BS服务器版本TCP服务器
public classBsTcpServer {public static void main(String[] args) throwsIOException {
ServerSocket server= new ServerSocket(8080);
Socket socket=server.accept();
InputStream ips=socket.getInputStream();byte[] bytes = new byte[1024];int len = 0;while ((len = ips.read(bytes))!= -1){
System.out.println(new String(bytes,0,len));
}
}
}
运行并访问
服务器输出为:
GET /testCOM.html HTTP/1.1 //地址请求的资源位置Host: localhost:8080Connection: keep-alive
Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36 Edg/83.0.478.54Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: goSessionid=xf82SLPFkJGHj5qZcl_lsO6XFT-FTHwjgVlxkkQdzWs%3D
GET /testCOM.html HTTP/1.1 可以使用BufferReader的方法readline读取一行
new BufferedReader(new InputStreamReader(is)) 将网络字节输入流转换为字符缓冲输入流
再使用String 类方法split(" ") 切割字符串,获取中间的部分
再使用String的方法substring(1)获取html文件的路径
testCOM.html
然后服务器建立一个本地字节输入流,根据获取到的文件路径读取html文件
服务器使用网络字节输出流把读取到的文件写道客户端即浏览器显示
固定的浏览器写入:
’
//写入HTTP协议响应投,固定写法
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("Content-Type:text/html\r\n".getBytes());//必须写入空行
out.write("\r\n".getBytes());
Server辰戌:
import java.io.*;importjava.net.ServerSocket;importjava.net.Socket;//BS服务器版本TCP服务器
public classBsTcpServer {public static void main(String[] args) throwsIOException {
ServerSocket server= new ServerSocket(8080);
Socket socket=server.accept();
InputStream ips=socket.getInputStream();//byte[] bytes = new byte[1024];//int len = 0;//while ((len = ips.read(bytes))!= -1){//System.out.println(new String(bytes,0,len));//}
BufferedReader br =new BufferedReader(newInputStreamReader(ips));
String line= br.readLine();//GET /resources/testCOM.html HTTP/1.1
String[] strings = line.split(" ");///resources/testCOM.html
String htmlpath = strings[1].substring(1);//resources/testCOM.html
FileInputStream fips= new FileInputStream(htmlpath); //resources/testCOM.html
OutputStream ops=socket.getOutputStream();//写入HTTP协议响应投,固定写法
ops.write("HTTP/1.1 200 OK\r\n".getBytes());
ops.write("Content-Type:text/html\r\n".getBytes());//必须写入空行
ops.write("\r\n".getBytes());int len = 0;byte[] bytes = new byte[1024];while ((len = fips.read(bytes)) != -1){
ops.write(bytes,0,len);
}
fips.close();
socket.close();
server.close();
}
}
结果: