来,大家接着看,说完了UDP传输呢,咱们说说这TCP传输,
说它之前,咱们还是要简单说一下它的特点。
就是面向连接,可靠地,建立通路后,可以传输大数据量。
其实大家UDP是不是也可以传输大数据量,但是UDP要分成小包往外发。
UDP玩的时候对应了对象,TCP是不是也要对应对象啊。
对吧,UDP分的是发送端和接收端。而到了TCP的时候,它分的是谁。
叫做客户端和服务端。
那么分别对应了两对象,第一个叫做Socket,第二个叫做ServerSocket。
大家从名字看ServerSocket是不是就是服务端,Socket客户端。
客户端服务端作为两个端点,建立完后就可以进行通信。
大家接下来注意看,我们先说一下客户端的问题。
来一个Socket,此类实现客户端套接字,套接字是两台机器间通信的端点。
socket():
客户端服务端依赖的是他们之间的通路,来进行传输。
所以这哥们一初始化,就去找服务端
空参数可以通过connect()连接服务端。
那么大家我们接下来演示下TCP的特点。注意看这。
/*
演示TCP传输:
1,tcp分客户端、服务端。
2,客户端对应的对象是Socket(),服务端是ServertSocket()。
*/
import java.net.*;
import java.io.*;
/*
客户端:
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。
因为tcp是面向连接的,所以在建立socket服务时,就要有服务端存在,
并连接成功。形成通路后,在该通道进行数据的传输。
需求:给服务端发送文本数据
步骤:
1,创建码头。
2,确定数据
2,发送数据,获取Socket流中的输出流。
3,关闭
*/
class TcpClient{
public static void main(String[] args)throws Exception{
//1,创建码头。
Socket s=new Socket("10.2.172.93",10003);
//2,确定数据。
OutputStream out=s.getOutputStream();
//3,发送数据流。
out.write("tcp ge men lai le".getBytes());
//4,关闭。
s.close();
}
}
/*
需求:定义端点接收数据并打印在控制台上。
步骤:
1,建立服务端的socket服务。ServerSocket()。
并监听一个端口。(创建码头)
2,获取连接过来的客户端对象,侦听并接收到此套接字的连接。
通过ServerSocket的accept方法。没有连接就会等,所以这个方法阻塞式的。
3,客户端如果发过来的数据,那么服务端要使用对应的客户端对象,
并获取到该客户端对象的读取流来读取发过来的数据。
并打印在控制台。
4,关闭。
*/
class TcpServer{
public static void main(String[] args)throws Exception{
//创建码头。
ServerSocket ss=new ServerSocket(10003);
//连接对象。
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
sop(ip+"..........connected");
//读取数据
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
sop(new String(buf,0,len));
//关闭
s.close();
ss.close();
}
public static void sop(Object obj){
System.out.println(obj);
}
}
12、TCP传输2
接下来大家我们说一说另外一个演示,前面呢,
我们给大家演示客户端给服务端发一个信息就发完了,并没有给服务端一个反馈信息。
现在呢我们做一个反馈动作。这个稍微有点麻烦,注意,演示TCP传输的客户端和服务端的互访。
import java.io.*;
import java.net.*;
/*
演示tcp传输的客户端和服务端的互访。
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。
*/
/*
客户端:
1,建立socket服务。指定要连接主机和端口。
2,获取socket流中的输出流,将数据写到该流中,通过网络发送给服务端。
3,获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
4,关闭客户端资源。
*/
class TcpClient2{
public static void main(String[] args)throws Exception{
//1,创建码头,标明发送目的地
Socket s=new Socket("10.2.172.93",10004);
//2,确定数据
OutputStream out=s.getOutputStream();
//3,发送数据
out.write("服务端,你好".getBytes());
//1,获取服务端反馈数据,并打印
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
sop(new String(buf,0,len));
//4,关闭客户端资源。
s.close();
}
public static void sop(Object obj){
System.out.println(obj);
}
}
class TcpServer2{
public static void main(String[] args)throws Exception{
//1,创建收货码头
ServerSocket ss=new ServerSocket(10004);
//2,连接对象
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
sop(ip+"........connected");
//3,读取数据
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
sop(new String(buf,0,len));
//1,向客户端反馈数据
OutputStream out=s.getOutputStream();
Thread.sleep(10000);
out.write("哥们收到,你也好".getBytes());
//4,关闭客户端资源。
s.close();
ss.close();
}
public static void sop(Object obj){
System.out.println(obj);
}
}
13、TCP练习
接下来我们通过一个练习,同时开发当中要用的一些对象以及TCP传输遇到的问题。
示例不重要,主要是里面遇到的问题。
/*
需求:建立一个文本转换服务器。
客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端。
而且服务端可以不断的进行文本转换,当客户端输入over时,转换结束。
客户端:
既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。
源:键盘录入。
目的:网络设备,网络输出流。
而且操作的是文本数据,可以选择字符流。
步骤:
1,创建码头。
2,获取录入。
3,发送数据。
4,自动获取反馈数据。
5,关闭。
字符流,提高效率,加入缓冲。
*/
import java.io.*;
import java.net.*;
class TransClient{
public static void main(String[] args)throws Exception{
//1,创建码头。
Socket s=new Socket("10.2.172.93",10004);
//2,定义键盘输入流。
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); //字节通向字符
//3,定义发送数据流。
//BufferedWriter bufOut=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); //字符通向字节
//作用同BufferedWriter一样,只是更简单。
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
//4,定义接收数据流,返回大写信息
BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream())); //字节通向字符
String line=null;
while((line=bufr.readLine())!=null){
if("886".equals(line))
break;
/*bufOut.write(line);
//line字符串的数据没有换行符,换行符是null的标记。
bufOut.newLine();
//刷新出缓冲区。
bufOut.flush();*/
out.println(line); //与PrintWriter配合
String str=bufIn.readLine();
sop("服务反馈:"+str);
}
//4,获取服务端反馈数据,并打印
/*InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
sop(new String(buf,0,len));*/
//5,关闭。
bufr.close();
s.close(); //返回-1
}
public static void sop(Object obj){
System.out.println(obj);
}
}
class TransServer{
public static void main(String[] args)throws Exception{
//1,创建码头。
ServerSocket ss=new ServerSocket(10004);
//2,连接对象。
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
sop(ip+"........connected");
//3,定义接收数据流。
BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream())); //字节通向字符
//4,定义接收数据流,返回大写信息
//定义发送数据流。
//BufferedWriter bufOut=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); //字符通向字节
//作用同BufferedWriter一样,只是更简单。
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
String line=null;
while((line=bufIn.readLine())!=null){ //客户端一停,readLine()接收到-1也就停了。
sop("客户端"+line);
//1,向客户端反馈数据
/*bufOut.write(line.toUpperCase());
bufOut.newLine();
//刷新
bufOut.flush();*/
out.println(line.toUpperCase()); //与PrintWriter配合
}
//4,关闭资源
s.close();
ss.close();
}
public static void sop(Object obj){
System.out.println(obj);
}
}
/*
该例子出现的问题。
现象:客户端和服务端都在莫名的等待。
为什么呢?
因为客户端和服务端都有阻塞式方法,这些方法都没有读到结束标记,就一直等。
而导致两端,互相等待。
*/
14、TCP复制文件
大家继续来看一个例子,刚才的例子,我们通过客户端键盘录入,
把它发送到客户端去,那么现在我们把客户端的一个文件数据发到服务端。
在服务端把数据存到一个文件中。
之前的例子是将文件从C盘拷贝到D盘,现在是从我的机器拷到你的机器上。
加上了网络技术,但是大家,是不是还是IO。
分了两端以后,客户端有自己的源和目的,服务端也有自己的源和目的。
大家接着看
import java.io.*;
import java.net.*;
class TextClient{
public static void main(String[] args)throws IOException{
//1,创建码头
Socket s=new Socket("10.2.172.93",10000);
//2,确定输入数据流
BufferedReader bufr=new BufferedReader(new FileReader("IPDemo.java"));
//3,定义发送数据流
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
String line=null;
while((line=bufr.readLine())!=null){
out.println(line);
}
s.shutdownOutput(); //关闭客户端的输出流,相当于给流中加入一个结束标记-1。
//4,定义接收数据流
BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream())); //字节通向字符
sop("服务端反馈:"+bufIn.readLine());
//5,关闭
bufr.close();
s.close();
}
public static void sop(Object obj){
System.out.println(obj);
}
}
class TextServer{
public static void main(String[] args)throws IOException{
//1,创建码头
ServerSocket ss=new ServerSocket(10000);
// 连接对象
Socket s=ss.accept();
//2,确定输入数据流
BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream())); //字节通向字符
//3,定义发送数据流
PrintWriter out=new PrintWriter(new FileWriter("server.txt"),true);
String line=null;
while((line=bufIn.readLine())!=null){
out.println(line);
}
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功");
//4,关闭资源
out.close();
s.close();
ss.close();
}
public static void sop(Object obj){
System.out.println(obj);
}
}