黑马程序员-网络编程之TCP传输小总结

来源:互联网 发布:制作结婚视频软件 编辑:程序博客网 时间:2024/06/11 14:46
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------


TCP传输:

Socket和ServerSocket分别表示TCP传输的两个端点,客户端和服务端,不同于UDP的DatagramSocket类既可以表示接收端也可以表示发送端。
客户端:
//创建客户端的Socket服务,指定目的主机和端口
//这一步一旦建立成功,就客户端和服务端之间就形成了字节流
Socket s=new Socket("127.0.0.1",10004);

//为了发送数据,应该获取Socket中的输出流。这个输出流是将字节写入此客户端Socket。一旦写入,就发送给服务器端。
//s.getOutputStream()对象的目的是服务器端中此Socket对象A对应的一个Socket对象A‘。服务器端将A'实例化后
//就通过A'的getInputStream()流的read来获取A的getOutputStream()流write出的数据。
OutputStream out=s.getOutputStream();

out.write("tcp ge men lai le".getBytes());

s.close();
服务器端:
//监理服务端socket服务,并监听一个端口。
ServerSocket ss=new ServerSocket(10004);

//通过accept方法获取链接过来的客户端Socket对象。
//accept方法是一个阻塞式方法,启动后会一直监听等着一个Socket来链接
Socket s=ss.accept();

//得到客户端对象的ip地址
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"..connected");

//获取客户端发送过来的数据,那么先在服务器端实例化一个客户端对应的Socket对象,然后通过这//个对象的getInputStream()
//流来获取客户端write出的数据
//s.getInputStream()流对象的源是客户端此Socket
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();//关闭服务端,可选操作

注意,说白了,其实就是客户端和服务端都有一个Socket对象,这两个对象都有自己的读写流,我写你读,我读你写。

/*演示Tcp传输 * 1 Tcp分客户端和服务端。 * 2 客户端对应的对象是Socket,服务端对应的对象是ServerSocket *  *  * *//* * 需求:给服务端发送一个文本数据。 * 客户端:通过查阅socket对象,发现在该对象建立时,就可以连接指定主机。 * 因为tcp是面向连接的,所以在建立socket服务时就要有服务端存在并连接成功。形成通路后,在该通道形成数据的传输 * 步奏: * 1,创建Socket服务,并指定要连接的主机和端口。 * 2, * */class TCPClient{public static void main(String []args) throws Exception{//创建客户端的Socket服务,指定目的主机和端口//这一步一旦建立成功,就客户端和服务端之间就形成了字节流Socket s=new Socket("127.0.0.1",10004);//为了发送数据,应该获取Socket中的输出流。这个输出流是将字节写入此客户端Socket。一旦写入,就发送给服务器端。//s.getOutputStream()对象的目的是服务器端中此Socket对象A对应的一个Socket对象A‘。服务器端将A'实例化后//就通过A'的getInputStream()流的read来获取A的getOutputStream()流write出的数据。OutputStream out=s.getOutputStream();out.write("tcp ge men lai le".getBytes());s.close();}}/* * 需求:定义端点接收数据并打印在控制台上。 *  * 服务端: * 1,建立服务端的Socket服务,通过ServerSocket()建立,并监听一个端口 * 2,获取链接过来的客户端对象。通过ServerSocket的accept方法。所以这个方是阻塞式的 * 3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据并打印 *    在控制台。 * 4,关闭服务端。(可选) * */class TCPServer{public static void main(String[]args) throws Exception{//监理服务端socket服务,并监听一个端口。ServerSocket ss=new ServerSocket(10004);//通过accept方法获取链接过来的客户端Socket对象。//accept方法是一个阻塞式方法,启动后会一直监听等着一个Socket来链接Socket s=ss.accept();//得到客户端对象的ip地址String ip=s.getInetAddress().getHostAddress();System.out.println(ip+"..connected");//获取客户端发送过来的数据,那么先在服务器端实例化一个客户端对应的Socket对象,然后通过这个对象的getInputStream()//流来获取客户端write出的数据//s.getInputStream()流对象的源是客户端此SocketInputStream 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();//关闭服务端,可选操作}}

/*演示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());//同样道理,客户端的Socket对象的getInputStream流的源是服务端的相应Socket对象,它write后我readInputStream 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();String ip=s.getLocalAddress().getHostAddress();System.out.println(ip+" ..connected");InputStream in=s.getInputStream();byte[] buf=new byte[1024];int len=in.read(buf);//read方法也是阻塞式的,客户端不来数据我就在这里等数据System.out.println(ip+"::"+new String(buf,0,len));OutputStream out=s.getOutputStream();out.write("哥们收到!你也好!".getBytes() );ss.close();}}


通过服务器端实现对输入字符串大小写互换功能。

/* * 需求:建立一个文本转换器。 * 客户端给服务端发送文本,服务端会将文本转成大写返回给客户端。 * 而且客户端可以不断的进行文本转换,当客户端输入over时,转换结束。 * */class TcpClient3{static BufferedReader br;static BufferedWriter bf;static BufferedReader br1;public static void main(String[]args) throws Exception{Socket s=new Socket("127.0.0.1",10005);OutputStream out=s.getOutputStream();br=new BufferedReader(new InputStreamReader(System.in));//读取键盘输入bf=new BufferedWriter(new OutputStreamWriter(out));//发送到服务端br1=new BufferedReader(new InputStreamReader(s.getInputStream()));//读取服务端发来的数据System.out.println("请输入:");String line=null;while((line=br.readLine())!=null ){//键盘输入若干字符和一个回车表示一行,readLine()读取了字符舍弃回车符。也就是说line中不包含回车符if(line.equals("over")) break;bf.write(line);bf.newLine();//再写入一个回车符bf.flush();System.out.println("服务器说:"+br1.readLine());}s.close();bf.close();br.close();br1.close();}}class TcpServer3{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:"+ip+"...connected");BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));String line=null;while((line=br.readLine())!=null){System.out.println(line);char b[]=line.toCharArray();for(int i=0;i<b.length;i++){if(b[i]<='z' && b[i]>='a')b[i]-=32;else if(b[i]<='Z' && b[i]>='A')b[i]+=32;}bw.write(new String(b));bw.newLine();bw.flush();}}
}

向服务器上传文本文件。

class TextClient{public static void main(String[]args) throws Exception{Socket s=new Socket("127.0.0.1",10006);BufferedReader br=new BufferedReader(new FileReader("D:\\workspace\\exam\\src\\com\\itheima\\Test9.java"));PrintWriter out=new PrintWriter(s.getOutputStream(),true);String line=null;while((line=br.readLine())!=null){out.println(line);}s.shutdownOutput();//关闭客户端的输出流。相当于给流中加入一个结束标记-1.BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));String line1=bufin.readLine();System.out.println(line1);br.close();s.close();bufin.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+" connnected");BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));PrintWriter out=new PrintWriter(new FileWriter("Server.txt"));String line=null;while((line=br.readLine())!=null){out.println(line);}PrintWriter pw=new PrintWriter(s.getOutputStream(),true);pw.println("恭喜你,上传成功!");out.close();s.close();ss.close();}}

并行向服务器上传图片。思想是服务端做成多线程。

/*向服务器上传图片*//* * 客户端: * 1,服务端点 * 2,读取客户端已有的图片数据 * 3,通过socket输出流发送给服务端 * 4,读取服务端反馈信息 * 5,关闭 * */class UpClient{public static void main(String[]args) throws Exception{if(args.length!=1){System.out.println("请选择一个图片文件");return;}File file=new File(args[0]);if(!(file.exists() && file.isFile())){System.out.println("文件不存在或不是文件");return;}if(!args[0].endsWith(".jpg")){System.out.println("请选择jpg文件");return;}if(file.length()>1024*1025*5){System.out.println("请选择小于5m的图片");return;}Socket s=new Socket("127.0.0.1",10007);BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));BufferedOutputStream bos=new BufferedOutputStream(s.getOutputStream());BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));byte[] b=new byte[1024];int len;while((len=bis.read(b))!=-1){bos.write(b, 0, len);bos.flush();}s.shutdownOutput();System.out.println(br.readLine());s.close();bis.close();bos.close();br.close();}}/* * 服务端的服务代码都写在线程类中,以实现并发。 * */class PicThread implements Runnable{private Socket s;PicThread(Socket s){this.s=s;}public void run(){String ip=s.getInetAddress().getHostAddress();int count=1;try {System.out.println(ip+"...connected");BufferedInputStream bis;bis = new BufferedInputStream(s.getInputStream());File file=new File("D:\\"+ip+"("+count+").jpg");//同一客户端发过来的图片名称都定义为它的ip号,以区别其他客户端while(file.exists()){//如果此名称已存在,即已有这个客户端发来图片,那么新传来的图片尾号自动加1,防止同名覆盖file=new File("D:\\"+ip+"("+(++count)+").jpg");}BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file));PrintWriter pw=new PrintWriter(s.getOutputStream(),true);int len;byte[] b=new byte[1024];while((len=bis.read(b))!=-1){bos.write(b, 0, len);}pw.println("上传完毕");s.close();bis.close();bos.close();pw.close();} catch (Exception e) {throw new RuntimeException(ip+"...上传失败");}}}/* * 服务器原理: * 将服务代码写入线程run方法,这样每次接收到一个新的请求时就开启一个线程。 * 之后主线程再次accept阻塞等待,再来新请求再次开启一个新线程。 * */class UpServer{public static void main(String[]args) throws Exception{ServerSocket ss=new ServerSocket(10007);while(true){Socket s=ss.accept();new Thread(new PicThread(s)).start();}}}



---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
0 0
原创粉丝点击