哎,怎么感觉自己变得懒了起来,更新博客的频率变得慢了起来,可能是因为最近得知识开始变得杂变得难了起来,之前在上课的时候,也没有好好听这一方面的知识,所以,现在可以说是在学的新的知识,要先去把新的知识思路屡了一遍,自己实现了代码,把整个过程以及规则搞懂了,我才会来总结博客。
说个有关这节知识的相关内容,
在学习网络编程之前,我们一定要先把I/O输入输出流给先学了,为什么这么说呢?仔细想想,我们学习网络编程,说到底还是数据之间的传输,文字,图片,音乐,视频等等也好,它们有的传输以及接收的方式不同,如果没有学习过I/O编程就来学习这个网络编程就略显困难,而我对I/O 流的学习还没有结束,因为有点多,我争取在本周把I/O流的章节的知识点和代码给总结出来。
好了,话不多说,如果你学过I/O输入输出流了,那么往下看(自学能力强的在学习网络编程的过程中就会慢慢总结到规律,。。),自己总结的,有啥不完整或者错误的欢迎私信补充和指出。
网络编程
1、计算机网络
什么是计算机网络?
是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
2、网络编程
就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。
图1 网络参考模型图
图2 网络应用程序是由网络编程,I/O流,多线程组成
3、网络编程的三要素
简单的故事开头方便理解:
我想和自己心爱的女孩说话了,怎么办?
第一步:我要找到这个女孩。 (IP地址)
第二步:对她说话,要对着耳朵说。 (端口)
第三步:我要说什么呢?“I Love You”,但是她听不懂英文,说汉语就可以了,我爱你。 (协议)
(1) IP地址
Ip地址是网络中计算机的唯一标识。端口是用来区分电脑上的应用程序。
计算机只能识别二进制的数据,所以我们的IP地址应该是一个二进制的数据。
但是,我们看电脑配置的IP地址却不是二进制的,这是为什么?
IP:192.168.1.103
换算:11000000 10101000 00000001 01100111
想想看,如果我们的Ip地址写成下面的二进制的话,不管是记忆还是书写都十分的麻烦,
所以,为了方便表示IP地址,我们就把IP地址的每一个字节上的数据换算成十进制,然后用 “点分十进制” 来表示。
IP地址的组成:网络号段+主机号段
A类:第一号段为网络号段+后三位的主机号段
一个网络号:256*256*256 = 16777216
B类:前二号段为网络号段+后两位的主机号段
一个网络号:256*256 = 65536
C类:前三号段为网络号段+后一位主机号段
一个网络号:256
拓展一下:
两个常用的DOS命令:
ipconfig:查看本机的IP地址
ping ip地址 :测试本机与指定的IP地址间的通信是否有问题
特殊的IP地址:
127.0.0.1 回环地址(表示本机)
X.X.X.255 广播地址
X.X.X.0 网络地址
为了方便方便我们获取IP地址和操作,Java提供了一个类InetAddress供我们使用,它是没有构造方法的,类中有静态方法返回该类的对象,类名调用。
(2)端口
正在运行的程序的标识
有效端口:0~65535,其中0~1024系统使用或者保留端口,一般情况下,我们使用10000以上的。
(3)协议
网络协议是网络上所有设备(网络服务器、计算机及交换机、路由器、防火墙等等)之间通信规则的集合,它规定了通信时信息必须采用的格式和这些格式的意义。尽管 TCP/IP 协议从名称看只包括 TCP 这个协议名,但是在 TCP/IP 协议的传输层同时存在 TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)两个协议。在网络通信中 TCP 协议类似于使用手机打电话,可以保证把信息传递给别人;而 UDP 协议类似于发短信,接收人有可能接收不到传递的信息。(UDP存在丢包)在网络通信中使用 TCP 的方式需要建立专门的虚拟连接,然后进行可靠的数据连接,如果数据发送失败,客户端会自动重发该数据。而使用 UDP 方式不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。TCP 协议是一种以固定连线为基础的协议,它提供两台计算机之间可靠的数据传送。而 UDP 无连接通信协议,它不保证可靠数据的传输,但能够向若干目标发送数据以及接收来自若干源的数据。对于一些重要的数据,一般使用 TCP 方式来进行数据传输,而大量的非核心数据则通过 UDP 方式进行传递。使用 TCP 方式传递的速度稍微慢一点,而且传输时产生的数据量会比 UDP 大一点。
4、协议UDP和TCP
(1)UDP
将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小限制在64k;因为它没有连接,是不可靠协议;不需要建立连接,速度快。
(2)TCP
建立连接。形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低。
分分钟了解什么是三次握手的视频网址 https://www.bilibili.com/video/av41782699?from=search&seid=15360378958258479001
5、Socket
(1)Socket套接字
网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一标识的标识套接字。
(2)Socket原理机制:
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过I/O传输
图3 Socket原理机制
6、UDP协议发送和接收数据
先看图解:
图4 UDP协议发送和接收数据
发送:
创建UDP发送端和Socket对象
创建数据,并把数据打包
调用Socket对象的发送方法发送数据包
释放资源
接收:
创建UDP接收端的Socket对象
创建数据包用于接收数据
调用Socket对象的接收方法接收数据包
解析数据包
释放资源
案例:
1、最基本的UDP协议发送和接收数据
send端:
package com.wyh.demo2; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.SocketException; /**
* @author WYH
* @version 2019年11月25日 下午6:46:00
*/
public class sendDemo1 {
public static void main(String[] args) throws IOException {
//创建Socket
DatagramSocket ds = new DatagramSocket();
//创建数据
byte[] buf = "你好,我是优化后的数据".getBytes();
int length = buf.length;
InetAddress address = InetAddress.getByName("192.168.1.103");
int port = 12345;
//打包数据
DatagramPacket dp = new DatagramPacket(buf, length, address, port);
//发送数据
ds.send(dp);
//释放资源
ds.close(); } }
service端:
package com.wyh.demo2; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException; /**
* @author WYH
* @version 2019年11月25日 下午6:40:16
*/
public class reciveDemo1 {
public static void main(String[] args) throws IOException {
//创建Socket对象
DatagramSocket ds = new DatagramSocket(12345); byte[] bt =new byte[1024];
//创建包裹
DatagramPacket dp = new DatagramPacket(bt, bt.length); //接收数据
ds.receive(dp); //解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(),0,dp.getLength());
System.out.println("主机名:"+ip+",接收的数据是:"+s); //释放资源
ds.close(); } }
2、把发送数据改进为键盘录入
send端:
package com.wyh.demo3; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress; /**
* @author WYH
* @version 2019年11月25日 下午6:46:00
*/
public class sendDemo1 {
public static void main(String[] args) throws IOException {
//创建Socket
DatagramSocket ds = new DatagramSocket();
//创建数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while((line = br.readLine())!=null) {
//当输入886的时候跳出
if("886".equals(line)) {
break;
}
byte[] buf = line.getBytes();
int length = buf.length;
InetAddress address = InetAddress.getByName("192.168.1.255");
int port = 12345;
//打包数据
DatagramPacket dp = new DatagramPacket(buf, length, address, port);
//发送数据
ds.send(dp);
} //释放资源
ds.close(); } }
service端:
package com.wyh.demo3; import java.io.IOException; import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException; /**
* @author WYH
* @version 2019年11月25日 下午6:40:16
*/
public class reciveDemo1 {
public static void main(String[] args) throws IOException {
//创建Socket对象
DatagramSocket ds = new DatagramSocket(12345); byte[] bt =new byte[1024];
//创建包裹
DatagramPacket dp = new DatagramPacket(bt, bt.length);
//while(true) 保证它可以一直可以接收数据
while(true) {
//接收数据
ds.receive(dp); //解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(),0,dp.getLength());
System.out.println("主机名:"+ip+",接收的数据是:"+s);
} //释放资源
//ds.close(); } }
3、一个简易聊天小程序并用多线程改进(实现Runnable接口的run方法)
sendThread:
package 多线程改进ChatRoom; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress; /**
* @author WYH
* @version 2019年11月25日 下午7:55:50
*/
public class SendThread implements Runnable{
private DatagramSocket ds; public SendThread(DatagramSocket ds) {
this.ds = ds;
} @Override
public void run() {
try {
//创建数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = br.readLine())!=null) {
if("886".equals(line)) {
break;
}
DatagramPacket dp = new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("192.168.1.103"), 12306);
ds.send(dp); }
//释放资源
ds.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
serviceThread:
package 多线程改进ChatRoom; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket; /**
* @author WYH
* @version 2019年11月25日 下午8:07:23
*/
public class ReciveThread implements Runnable {
private DatagramSocket ds; public ReciveThread(DatagramSocket ds) {
this.ds = ds;
} @Override
public void run() {
try {
while (true) {
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b, b.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getData().length); System.out.println("主机号:" + ip + "发来:" + s);
}
} catch (IOException e) {
e.printStackTrace();
}
} }
主函数:
package 多线程改进ChatRoom; import java.io.IOException;
import java.net.DatagramSocket; /**
* @author WYH
* @version 2019年11月25日 下午7:52:39
*/
public class chatRoom {
public static void main(String[] args) throws IOException{
DatagramSocket dsSend = new DatagramSocket();
DatagramSocket dsRecive = new DatagramSocket(12306); SendThread st = new SendThread(dsSend);
ReciveThread rt = new ReciveThread(dsRecive); Thread t1 = new Thread(st);
Thread t2 = new Thread(rt); t1.start();
t2.start();
} }
7、TCP协议发送和接收数据
先看图解:
图5 TCP协议发送和接收数据
发送:
创建TCP客户端的Socket对象
获取输出露,写数据
释放数据
接收:
创建TCP服务端的Socket对象
监听客户端连接
获取输入流,读取数据
释放资源(注意,所有有关文件的操作,都要进行关闭操作(.close())!!!!!!!)
案例:
1、最基本的TCP协议发送和接收数据
Client:
package TCP协议; import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException; /**
* @author WYH
* @version 2019年11月26日 下午7:17:58
*
*
* TCP一定要先开启服务端
* java.net.ConnectException: Connection refused: connect
*
*/
public class Clint {
public static void main(String[] args) throws IOException {
//创建TCP协议的Socket对象
Socket s = new Socket("192.168.1.103",9998); //获取输出流
OutputStream os = s.getOutputStream();
os.write("hello,TCP来了。。".getBytes()); //释放资源
s.close(); } }
Server:
package TCP协议; import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* @author WYH
* @version 2019年11月26日 下午7:28:59
*/
public class Server {
public static void main(String[] args) throws IOException {
// 获取服务器端的Socket
ServerSocket ss = new ServerSocket(9998);
// 进行监听返回一个Socket对象
Socket s = ss.accept();
InputStream is = s.getInputStream();
//获取客户端IP地址
String s2 = s.getInetAddress().getHostAddress(); //进行获取字节流并输出到控制台
byte[] b = new byte[1024];
int len;
while ((len = is.read(b)) != -1) {
String s1 = new String(b, 0, len);
System.out.println(s2+":"+s1);
} // 释放资源
s.close();
ss.close(); } }
2、服务器给出反馈:
client:
package TCP协议_1; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket; /**
* @author WYH
* @version 2019年11月26日 下午7:17:58
*
*
* TCP一定要先开启服务端
* java.net.ConnectException: Connection refused: connect
*
*/
public class Clint {
public static void main(String[] args) throws IOException {
//创建TCP协议的Socket对象
Socket s = new Socket("192.168.1.103",9997); //获取输出流
OutputStream os = s.getOutputStream();
os.write("hello,TCP来了。。".getBytes()); //接收服务器端的反馈
InputStream is = s.getInputStream();
byte[] b = new byte[1024];
int len;
while((len = is.read(b))!=-1) {
String s1 = new String(b,0,len);
System.out.println(s1);
} //释放资源
s.close(); } }
Server:
package TCP协议_1; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* @author WYH
* @version 2019年11月26日 下午7:28:59
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9997);
Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String s1 = new String(bys,0,len);
System.out.println(ip+":"+s1); //发送反馈
OutputStream os = s.getOutputStream();
os.write("数据我已经收到了".getBytes()); s.close();
ss.close(); } }
3、客户端键盘录入,服务器端控制台输出
Client:
package TCP协议_2; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket; /**
* @author WYH
* @version 2019年11月26日 下午7:17:58
* 客户端键盘录入,服务器端控制台输出
*
*
* TCP一定要先开启服务端 java.net.ConnectException: Connection refused: connect
*
*/
public class Clint {
public static void main(String[] args) throws IOException {
// 创建TCP协议的Socket对象
Socket s = new Socket("192.168.1.103", 9997); /*
* Scanner sc =new Scanner(System.in); System.out.print("请输入想要发送的数据:"); String
* info = sc.next();
*/
System.out.print("请输入想要发送的数据:");
//键盘录入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//包装通道流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line;
while ((line = br.readLine()) != null) {
//键盘录入的一定要自定义结束
if ("886".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
// 释放资源
s.close(); } }
Server:
package TCP协议_2; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* @author WYH
* @version 2019年11月26日 下午7:28:59
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9997);
Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); //包装通道里的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(ip + ":" + line);
} s.close(); } }
4、客户端键盘录入,服务器写到文件里
Client:
package TCP协议_3; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket; /**
* @author WYH
* @version 2019年11月26日 下午7:17:58
* 客户端键盘录入,服务器端输出到文本文件
*
*
* TCP一定要先开启服务端 java.net.ConnectException: Connection refused: connect
*
*/
public class Clint {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.1.103",2222); BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line = null;
while((line = br.readLine())!=null) {
if("886".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
} s.close(); }
}
Server:
package TCP协议_3; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* @author WYH
* @version 2019年11月26日 下午7:28:59
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(2222); Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress(); BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null;
while((line = br.readLine())!=null) {
System.out.println(ip+":"+line);
//封装要写入的文件
BufferedWriter br1 = new BufferedWriter(new FileWriter("D://TCP测试.txt",true));
br1.write(line);
br1.newLine();
br1.close(); } s.close(); } }
5、客户端读取文本文件,服务器端控制台输出
Client:
package TCP协议_4; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket; import javax.annotation.processing.Filer;
import javax.lang.model.element.Element;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileManager.Location; /**
* @author WYH
* @version 2019年11月26日 下午7:17:58
* 客户端文本文件,服务器端输出到控制台
*
*
* TCP一定要先开启服务端 java.net.ConnectException: Connection refused: connect
*
*/
public class Clint {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.1.103",2222);
//封装文本文件
BufferedReader br = new BufferedReader(new FileReader("D://TCP测试.txt")); //封装通道流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while((line = br.readLine())!= null) {
bw.write(line);
bw.newLine();
bw.flush();
} bw.close();
s.close();
}
}
Server:
package TCP协议_4; import java.io.BufferedReader; import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* @author WYH
* @version 2019年11月26日 下午7:28:59
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(2222); Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress(); //封装通道流
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while ((line = br.readLine()) != null) {
System.out.println(ip+":"+line);
}
br.close();
s.close(); } }
6、客户端读取文本文件,服务器端写入到新的文本文件,模拟文件上传
Client:
package TCP协议_5; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket; import javax.annotation.processing.Filer;
import javax.lang.model.element.Element;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileManager.Location; /**
* @author WYH
* @version 2019年11月26日 下午7:17:58
* 客户端文本文件,服务器端输出到文本,并接收到来自服务器的反馈
*
*
*
*
* TCP一定要先开启服务端 java.net.ConnectException: Connection refused: connect
*
*/
public class Clint {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.1.103",2222);
//封装文本文件
BufferedReader br = new BufferedReader(new FileReader("D://TCP测试.txt")); //封装通道流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while((line = br.readLine())!= null) {
bw.write(line);
bw.newLine();
bw.flush();
} //方法1 自定义通知服务器我读取文件结束,但是不好
//如果我要读取的文本文件过程中有该自定义,那么就被中止了,所以我们采用第二种方式
/*bw.write("over");
bw.newLine();
bw.flush();*/ //方式2 采用Socket提供的方法
s.shutdownOutput(); BufferedReader br1 = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line1 = br1.readLine();
System.out.println(line1); bw.close();
s.close();
}
}
Server:
package TCP协议_5; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; /**
* @author WYH
* @version 2019年11月26日 下午7:28:59
*/
public class Server {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket ss = new ServerSocket(2222); Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress(); //封装通道流
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw = new BufferedWriter(new FileWriter("TCP_5.txt",true));
String line1 = null;
while((line1 = br.readLine())!=null) {
/*if("over".equals(line1)) {
break;
}*/
bw.write(line1);
bw.newLine();
bw.flush();
Thread.sleep(2000);//这里我添加了一个线程睡眠,为了更逼真的模拟
System.out.println("文件复制中。。");
} BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
Scanner sc = new Scanner(System.in);
String s1 = sc.next();
bwServer.write(s1);
bwServer.newLine();
bwServer.flush();
System.out.println("文件复制成功"); bw.close();
br.close();
s.close(); } }
7、上传图片(字节流进行传输)
Client:
package TCP协议_6图片; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket; import javax.annotation.processing.Filer;
import javax.lang.model.element.Element;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileManager.Location; /**
* @author WYH
* @version 2019年11月26日 下午7:17:58
* 客户端发送图片,服务器端接收图片
*
*
*
*
* TCP一定要先开启服务端 java.net.ConnectException: Connection refused: connect
*
*/
public class Clint {
public static void main(String[] args) throws IOException {
//获取Socket对象
Socket s = new Socket("192.168.1.103", 19191); //封装图片
BufferedInputStream bi = new BufferedInputStream(new FileInputStream("timg.jpg"));
//封装通道流
BufferedOutputStream bo = new BufferedOutputStream(s.getOutputStream()); byte[] bys = new byte[1024];
int len;
while((len = bi.read(bys))!=-1){
bo.write(bys,0,len);
bo.flush();//为了保证没有精度丢失
}
s.shutdownOutput(); //接收反馈
InputStream is = s.getInputStream();
byte[] bys2 = new byte[1024];
int len1 = is.read(bys2);
String s1 = new String(bys2,0,len1);
System.out.println(s1); bi.close();
s.close(); }
}
Server:
package TCP协议_6图片; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; /**
* @author WYH
* @version 2019年11月26日 下午7:28:59
*/
public class Server {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket ss = new ServerSocket(19191); Socket s = ss.accept(); BufferedInputStream bi = new BufferedInputStream(s.getInputStream()); BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream("copy.jpg"));
byte[] bys = new byte[1024];
int len;
while((len = bi.read(bys))!= -1){
bo.write(bys,0,len);
bo.flush();//为了保证没有精度丢失
} OutputStream ow = s.getOutputStream();
ow.write("图片上传成功".getBytes()); bo.close();
s.close(); } }
8、多线程改进上传文件(思路:服务器端实现Runnable接口,重写run方法)
Client:
package TCP协议_7Thread; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket; import javax.annotation.processing.Filer;
import javax.lang.model.element.Element;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileManager.Location; /**
* @author WYH
* @version 2019年11月26日 下午7:17:58
* 客户端文本文件,服务器端输出到文本,并接收到来自服务器的反馈
*
*
*
*
* TCP一定要先开启服务端 java.net.ConnectException: Connection refused: connect
*
*/
public class Clint {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.1.103",2222);
//封装文本文件
BufferedReader br = new BufferedReader(new FileReader("D://TCP测试.txt")); //封装通道流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while((line = br.readLine())!= null) {
bw.write(line);
bw.newLine();
bw.flush();
}
s.shutdownOutput(); BufferedReader br1 = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line1 = br1.readLine();
System.out.println(line1); bw.close();
s.close();
}
}
Serve实现Runnable接口,重写run方法类:
package TCP协议_7Thread; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner; public class StudentThread implements Runnable { private Socket s;
public StudentThread(Socket s){
this.s = s;
} @Override
public void run(){
try{
String ip = s.getInetAddress().getHostAddress();
//封装通道流
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String newFile = System.currentTimeMillis()+".txt"; BufferedWriter bw = new BufferedWriter(new FileWriter(newFile,true));
String line1 = null;
while((line1 = br.readLine())!=null) {
/*if("over".equals(line1)) {
break;
}*/
bw.write(line1);
bw.newLine();
bw.flush();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("文件上传中。。");
} BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
// Scanner sc = new Scanner(System.in);
// String s1 = sc.next();
bwServer.write("文件上传成功");
bwServer.newLine();
bwServer.flush();
System.out.println("文件上传成功"); bw.close();
br.close();
s.close(); }catch(IOException e){
e.printStackTrace();
}
} }
Server:
package TCP协议_7Thread; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; /**
* @author WYH
* @version 2019年11月26日 下午7:28:59
*/
public class Server {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket ss = new ServerSocket(2222);
while(true){
Socket s = ss.accept();
new Thread(new StudentThread(s)).start();
}
} }
(后面整理发现,我的Client的类名写错了,英文不好,请见谅,嘿嘿,自行修改一下类名即可)
再次提醒:(注意,所有有关文件的操作,都要进行关闭操作(.close())!!!!!!!)