TCP传输:
1·包括客户端和服务端,即Socket为客户端,ServerSocket为服务端。
2·创建服务端对象:ServerSocket(int port):指定接收的客户端的端口
3·Socket accept():真挺并接受到此套接字的连接
4·void shutdownInput():此套接字的输入流至于“流的末尾”
5·void shutdownOutput():禁用此套接字的输出流
6·InputStream getInputStream():返回此套接字的输入流
7·OutputStream getOutputStream():返回套接字的输出流
客服端:
/*
演示tcp传输。
1,tcp分客户端和服务端。
2,客户端对应的对象是Socket。
服务端对应的对象是ServerSocket。
*/
/*
客户端,
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。
因为tcp是面向连接的。所以在建立socket服务时,
就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。
需求:给服务端发送给一个文本数据。
*/
import java.io.*;
import java.net.*;
class TcpClient
{
public static void main(String[] args) throws Exception
{
//创建客户端的socket服务。指定目的主机和端口
Socket s = new Socket("127.0.0.1",10003);
//为了发送数据,应该获取socket流中的输出流。
OutputStream out = s.getOutputStream();
out.write("tcp ge men lai le ".getBytes());
s.close();
}
}
服务端:
/*
需求:定义端点接收数据并打印在控制台上。
服务端:
1,建立服务端的socket服务。ServerSocket();
并监听一个端口。
2,获取连接过来的客户端对象。
通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。
并打印在控制台。
4,关闭服务端.(可选)
*/
class TcpServer
{
public static void main(String[] args) throws Exception
{
//建立服务端socket服务。并监听一个端口。
ServerSocket ss = new ServerSocket(10003);
//通过accept方法获取连接过来的客户端对象。
while(true)
{
Socket s = ss.accept();
//从客户端对象获取ip地址
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....connected");
//获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();//关闭客户端.
}
//把服务端也关闭了
//ss.close();
}
}
import java.io.*;
import java.net.*;
/*
演示tcp的传输的客户端和服务端的互访。
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。
*/
/*
客户端:
1,建立socket服务。指定要连接主机和端口。
2,获取socket流中的输出流。将数据写到该流中。通过网络发送给服务端。
3,获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
4,关闭客户端资源。
*/
class TcpClient2
{
public static void main(String[] args)throws Exception
{
Socket s = new Socket("127.0.0.1",10004);
OutputStream out = s.getOutputStream();
out.write("服务端,你好".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();
}
}
class TcpServer2
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10004);
Socket s = ss.accept();
//得到客户端的ip地址
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....connected");
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
OutputStream out = s.getOutputStream();
Thread.sleep(10000);
out.write("哥们收到,你也好".getBytes());
s.close();
//把服务端也关闭了
ss.close();
}
}
TCP练习:
需求:建立一个文本转换服务器
客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。
而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。
分析:
客户端:
既然是操作设备上的数据,那么就可以用IO技术,并依IO操作规律操作。
源:键盘录入;
目的:网络设备,即网络输出流。
-->操作的是文本数据,可选字符流,并加入高效缓冲区。
步骤:
- 建立服务。
- 获取键盘录入
- 将数据发给服务端
- 之后去服务端返回数据
- 结束,关闭资源
import java.io.*;
import java.net.*;
class TransClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("127.0.0.1",10005);
//定义读取键盘数据的流对象。
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
//定义目的,将数据写入到socket输出流。发给服务端。
//BufferedWriter是字符流,getOutputStream()是字节流,所以要通过OutputStreamWriter转化
//BufferedWriter bufOut =
//new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//定义一个socket读取流,读取服务端返回的大写信息。
BufferedReader bufIn =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
out.println(line);
// bufOut.write(line);
// bufOut.newLine();
// bufOut.flush();
String str =bufIn.readLine();
System.out.println("server:"+str);
}
bufr.close();
s.close();
}
}
服务端:
源:socket读取流;
目的:socket输出流。
注:socket的close()方法中加入了结束标记-1,所以客户端结束了,服务端也结束了。
/*
服务端:
源:socket读取流。
目的:socket输出流。
都是文本,装饰。
*/
class TransServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10005);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....connected");
//读取socket读取流中的数据。
BufferedReader bufIn =
new BufferedReader(new InputStreamReader(s.getInputStream()));
//目的。socket输出流。将大写数据写入到socket输出流,并发送给客户端。
//BufferedWriter bufOut =
//new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//<span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">可用PrintWriter(s.getOutputStrean(),true)创建输出流对象,true作用是刷新,通过打印方法println()换行,“ln”表示换行</span>
String line = null;
while((line=bufIn.readLine())!=null)
{
System.out.println(line);
//toUpperCase()将字符转换成大写
out.println(line.toUpperCase());
// bufOut.write(line.toUpperCase());
// bufOut.newLine();
// <span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">可用高效缓冲区类的newLine()换行作为结束标记,并用flush()进行刷新。</span>
// bufOut.flush();
}
//s.close()
s.close();
//<span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">socket的close()方法中加入了结束标记-1,所以客户端结束了,服务端也结束了。</span>
ss.close();
}
}
TCP复制文件:
可能出现的问题:
1·文件已经上传成功了,但是没有得到服务端的反馈信息。
2·即使得到反馈信息,但得到的是null,而不是“上传成功”的信息
原因:
1.因为客户端将数据发送完毕后,服务端仍然在等待这读取数据,并没有收到结束标记,就会一直等待读取。
2.上个问题解决后,收到的不是指定信息而是null,是因为服务端写入数据后,也需要刷新,才能将信息反馈给客服端。
解决:
方法一:定义结束标记,先将结束标记发送给服务端,让服务端接收到结束标记,然后再发送上传的数据。但是这样定义可能会发生定义的标记和文件中的数据重复而导致提前结束。
方法二:定义时间戳,由于时间是唯一的,在发送数据前,先获取时间,发送完后在结尾处写上相同的时间戳,在服务端,接收数据前先接收一个时间戳,然后在循环中判断时间戳以结束标记。
方法三:通过socket方法中的shutdownOutput(),关闭输入流资源,从而结束传输流,以给定结束标记。这里主要用这个方法。
import java.io.*;
import java.net.*;
class TextClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("127.0.0.1",10006);
BufferedReader bufr =
new BufferedReader(new FileReader("IPDemo.java"));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
// DataOutputStream dos=new DataOutputStream(s.getOutputStream());
// long time=System.currentTimeMillis();
// out.println(time);
// dos.writeLong(time);
String line = null;
while((line=bufr.readLine())!=null)
{
out.println(line);
}
// dos.writeLong(time);
s.shutdownOutput();//关闭客户端的输出流。相当于给流中加入一个结束标记-1.
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = bufIn.readLine();
System.out.println(str);
bufr.close();
s.close();
}
}
class TextServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10006);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....connected");
// DataInputStream dis=new DataInputStream(s.InputStream());
// long l=dis.readLong();
// BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(new FileWriter("server.txt"),true);
String line = null;
while((line=bufIn.readLine())!=null)
{
//if("over".equals(line))
//break;
out.println(line);
}
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功");
out.close();
s.close();
ss.close();
}
}
图片复制:
客户端:
- 创建服务端点
- 读取客户端以后图片数据
- 通过Socket输出流将数据发给服务端
- 读取服务端反馈信息
- 关闭客户端
/*
需求:上传图片。
*/
/*
客户端。
1,服务端点。
2,读取客户端已有的图片数据。
3,通过socket 输出流将数据发给服务端。
4,读取服务端反馈信息。
5,关闭。
*/
import java.io.*;
import java.net.*;
class PicClient
{
public static void main(String[] args)throws Exception
{
Socket s = new Socket("192.168.1.254",10007);
FileInputStream fis = new FileInputStream("c:\\1.bmp");
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1)
{
out.write(buf,0,len);
}
//告诉服务端数据已写完
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int num = in.read(bufIn);
System.out.println(new String(bufIn,0,num));
fis.close();
s.close();
}
}
服务端:
class PicServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10007);
Socket s = ss.accept();
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("server.bmp");
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1)
{
fos.write(buf,0,len);
}
OutputStream out = s.getOutputStream();
out.write("上传成功".getBytes());
fos.close();
s.close();
ss.close();
}
}
----------- java培训、java技术博客、期待与您交流! ------------