Java 网络编程三 TCP传输协议(例:传输文本、图片)

来源:互联网 发布:送男生生日礼物知乎 编辑:程序博客网 时间:2024/06/05 18:50

TCP传输

TCP Socket:IP地址和端口,套接字

Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket  

同样,客户端与服务器端是两个独立的应用程序。


☆基本思路(客户端)

客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异常。
连接成功,说明客户端与服务端建立了通道,那么通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通过getInputStream(), getOutputStream()获取即可。
与服务端通讯结束后,关闭Socket。

☆基本思路(服务器端)

服务端需要明确它要处理的数据是从哪个端口进入的。
当有客户端访问时,要明确是哪个客户端,可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输。
当该客户端访问结束,关闭该客户端。

基于TCP的Socket通信流程



☆客户端

通过Socket建立对象并指定要连接的服务端主机以及端口。

Socket s = new Socket(“192.168.1.1”,9999);OutputStream out = s.getOutputStream();out.write(“hello”.getBytes());s.close();
☆服务器端
建立服务端需要监听一个端口

ServerSocket ss = new ServerSocket(9999);Socket s = ss.accept ();InputStream in = s.getInputStream();byte[] buf = new byte[1024];int num = in.read(buf);String str = new String(buf,0,num);System.out.println(s.getInetAddress().toString()+”:”+str);s.close();ss.close();
1.下面模拟一下TCP传输协议传输

客户端:

package cn.hncu.net.tcp.demo;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;/** * @author<a href="mailto:794530831@qq.com">dragon_Dai</a> * @version 2017-8-13 下午8:51:29 * @filename MySocketClient.java *  * TCP传输编程 * 客户端:(Socket) * 服务器:(ServerSocket) */public class MySocketClient {public static void main(String[] args) {try {//创建一个Socket对象//尝试向指定"IP+端口号"的那台服务器发出"握手"申请,如果握手等待时间超时则会抛出异常.Socket s=new Socket("127.0.0.1", 10005);//如果程序可以运行到此处,说明上一句代码每一出现异常,表示"握手"成功,接下来就可以通过s和对方(服务器)进行通讯了//通过流来向服务器发送传输的信息OutputStream os=s.getOutputStream();os.write("来自客户端的传输信息".getBytes());//接收服务器返回的提示信息InputStream is=s.getInputStream();int len=-1;byte bs[]=new byte[512];while((len=is.read(bs))!=-1){System.out.println(new String(bs, 0, len));}//关流os.close();is.close();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
服务器:

package cn.hncu.net.tcp.demo;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;/** * @author<a href="mailto:794530831@qq.com">dragon_Dai</a> * @version 2017-8-13 下午9:05:05 * @filename MySocketServer.java *  * TCP传输编程 * 客户端:(Socket) * 服务器:(ServerSocket) */public class MySocketServer {public static void main(String[] args) {try {//创建一个ServerSocket对象ServerSocket server=new ServerSocket(10005);//指定服务器的端口号while(true){//服务器一打开就一直等待客户端来通讯(握手)Socket s = server.accept();//阻塞方法,返回值为对方的Socket对象//程序运行到此处说明上一句每一异常,表示握手成功.//通过流来读取客户端传输过来的信息InputStream in=s.getInputStream();String ip=s.getInetAddress().getHostAddress();System.out.println("ip:"+ip);int len=-1;byte bs[]=new byte[512];len=in.read(bs);System.out.println(new String(bs, 0, len));//读取完之后,向客户端,返回一些提示信息.//通过流来返回信息OutputStream os=s.getOutputStream();os.write("来自服务器的提示信息".getBytes());//关流os.close();in.close();}} catch (IOException e) {e.printStackTrace();}}}
客户端显示

来自服务器的提示信息

服务器显示

ip:127.0.0.1来自客户端的传输信息
2.下面模拟客户端读取一个本地文本文件,发向服务器,服务器存储起来
客户端

package cn.hncu.net.tcp.uploadTextFile;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;/** * @author<a href="mailto:794530831@qq.com">dragon_Dai</a> * @version 2017-8-13 下午9:49:22 * @filename UploadTextClient.java *  *读取一个本地文本文件,将数据发送到服务端,服务器端对数据进行存储。  * 存储完毕后,给客户端一个提示。 */public class UploadTextClient {public static void main(String[] args) {try {//创建一个Socket对象Socket s=new Socket("127.0.0.1",10006);//1.向服务器上传文件//目的BufferedReader br=new BufferedReader(new FileReader("wenben.txt"));//源PrintWriter pw=new PrintWriter(s.getOutputStream(),true);String str=null;while((str=br.readLine())!=null){pw.println(str);}//这里因为下面还需要接收服务器返回的信息,而服务器一直在读,所以这里需要告诉服务器,写入数据完毕s.shutdownOutput();//2.接收服务器返还信息BufferedReader br2=new BufferedReader(new InputStreamReader(s.getInputStream()));String str2=null;while((str2=br2.readLine())!=null){System.out.println(str2);}//关流br.close();pw.close();br2.close();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}
服务器
package cn.hncu.net.tcp.uploadTextFile;import java.io.BufferedReader;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;/** * @author<a href="mailto:794530831@qq.com">dragon_Dai</a> * @version 2017-8-13 下午9:54:54 * @filename UploadTextServer.java *  *读取一个本地文本文件,将数据发送到服务端,服务器端对数据进行存储。  * 存储完毕后,给客户端一个提示。 */public class UploadTextServer {public static void main(String[] args) {try {//创建一个ServerSocket对象ServerSocket server=new ServerSocket(10006);//指定服务器的端口号while(true){Socket s=server.accept();//阻塞方法,返回值为对方的Socket对象//程序运行到此处说明上一句每一异常,表示握手成功.//通过流来读取客户端传输过来的信息BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));//存入到File中。//I/O 流的介绍 与使用  总结,在前面的博客中有写过。PrintWriter pw=new PrintWriter(new FileWriter("server.txt"),true);//自动刷缓存String str=null;while((str=br.readLine())!=null){pw.println(str);}//读取完毕之后,给客户端发送读取完毕的信息PrintWriter pw2=new PrintWriter(s.getOutputStream(),true);pw2.println("上传成功");//关流br.close();pw.close();pw2.close();}} catch (IOException e) {e.printStackTrace();}}}
客户端读取的wenben.txt
本地文本文件-------over
客户端收到服务器的提示信息:(我这里是在MyEclipse的控制台显示)

上传成功
服务器存储的server.txt文件:

本地文本文件-------over

3.下面客户端向服务器发送图片

客户端:

package cn.hncu.net.tcp.uploadPicFile;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;import java.net.UnknownHostException;import javax.swing.JFileChooser;import javax.swing.JOptionPane;/** * @author<a href="mailto:794530831@qq.com">dragon_Dai</a> * @version 2017-8-13 下午11:48:46 * @filename UploadPicClient.java *  * 客户端需求:把一个图片文件发送到服务端并读取回馈信息。 *      要求判断文件是否存在及格式是否为jpg或gif并要求文件小于2M。 * 服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个 上传成功字样。 *    支持多用户的并发访问(这里需要多线程)。 */public class UploadPicClient {public static void main(String[] args) {//先让用户选择文件JFileChooser jfc=new JFileChooser();int res = jfc.showOpenDialog(null);//选中了文件才进行通讯if(res==JFileChooser.APPROVE_OPTION){//卫条件if(!jfc.getSelectedFile().getName().endsWith(".jpg") && !jfc.getSelectedFile().getName().endsWith(".gif")){JOptionPane.showMessageDialog(null, "文件格式选择错误,只能选择.jpg或者.gif文件");return;}if(jfc.getSelectedFile().length()>1024*1024*2){JOptionPane.showMessageDialog(null, "文件不能大于2M");return;}try {Socket s=new Socket("127.0.0.1",10007);//源 fileBufferedInputStream bis=new BufferedInputStream(new FileInputStream(jfc.getSelectedFile()));//目的 SocketBufferedOutputStream bos=new BufferedOutputStream(s.getOutputStream());byte bs[]=new byte[512];int len=-1;while((len=bis.read(bs))!=-1){bos.write(bs, 0, len);}bos.flush();//缓存流需要刷缓存s.shutdownOutput();//提示服务器,传输数据完毕//接收服务器返回的提示信息BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));String str=null;while((str=br.readLine())!=null){System.out.println(str);}//关流bis.close();bos.close();br.close();s.close();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}} 
服务器

package cn.hncu.net.tcp.uploadPicFile;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;/** * @author<a href="mailto:794530831@qq.com">dragon_Dai</a> * @version 2017-8-13 下午11:46:50 * @filename UploadPicServer.java *  * 客户端需求:把一个图片文件发送到服务端并读取回馈信息。 *      要求判断文件是否存在及格式是否为jpg或gif并要求文件小于2M。 * 服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个 上传成功字样。 *    支持多用户的并发访问(这里需要多线程)。 */public class UploadPicServer {public static void main(String[] args) {try {ServerSocket server=new ServerSocket(10007);while(true){Socket s=server.accept();new Thread(new UploadThread(s)).start();}} catch (IOException e) {e.printStackTrace();}}}class UploadThread implements Runnable{private Socket s;public UploadThread(Socket s) {this.s=s;}@Overridepublic void run() {String ip=s.getInetAddress().getHostAddress();System.out.println("ip="+ip+" 连接到服务器");//接收文件try {BufferedInputStream bis=new BufferedInputStream(s.getInputStream());//服务器接收到的文件,存储到新的文件,新的文件命名(在这里我通过 ip+"count++"+".jpg")File dir=new File("pics");if(!dir.exists()){dir.mkdirs();}int count=1;File file=new File(dir,ip+(count++)+".jpg");while(file.exists()){file=new File(dir,ip+(count++)+".jpg");}BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file));byte bs[]=new byte[512];int len=-1;while((len=bis.read(bs))!=-1){bos.write(bs, 0, len);}bos.flush();//缓存流需要刷缓存//给服务器返回信息OutputStream os=s.getOutputStream();os.write("上传成功".getBytes());//关流bis.close();bos.close();os.close();s.close();} catch (IOException e) {//如果发生异常,向客户端发送上传失败的信息try {OutputStream os=s.getOutputStream();os.write("上传失败".getBytes());} catch (IOException e1) {throw new RuntimeException("Socket出现异常");}}}}
这里客户端可以多次运行,向服务器发送图片文件.


原创粉丝点击