`
把阳光剪成雨Java
  • 浏览: 24032 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

黑马程序员——TCP协议

阅读更多

 ----------------------------android培训java培训、期待与您交流!----------------------------

TCP和其他技术

1.TCP的传输。

      SocketServerSocket,建立客户端和服务器端。建立连接后,通过Socket中的IO流进行数据的传输。关闭Socket。同样,客户端和服务器端是两个独立的应用程序。

 

/*

演示tcp传输。

1,tcp分客户端和服务端。

2,客户端对应的对象是Socket

    服务端对应的对象是ServerSocket

*/

/*

客户端,

通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。

因为tcp是面向连接的。所以在建立socket服务时,

就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。

 

需求:给服务端发送给一个文本数据。

步骤:

1,创建Socket服务。并指定要连接的主机和端口。

*/

import java.io.*;

import java.net.*;

class  TcpClient

{

    public static void main(String[] args) throws Exception

    {

       //创建客户端的socket服务。指定目的主机和端口

       Socket s = new Socket("192.168.1.254",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();

 

       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();

    }

}

 

2.TCP客户端和服务端的相互转发。

服务器端:

public class TcpTransServer {

    public static void main(String[] args) {

       //创建socket服务端。

       try {

           ServerSocket ss = new ServerSocket(12345);

           // 获取socket

           Socket s = ss.accept();

           // s中获取流,读取数据。

           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("client:" + line);

 

              // 读取客户端数据,并将它转换成大写的。然后再发往客户端。客户端的readLine方法在等待服务器端

              // socket里面写入数据。

              bw.write(line.toUpperCase());

              bw.newLine();

              bw.flush();

           }

           s.close();

           ss.close();

       } catch (IOException e) {

           e.printStackTrace();

       }

    }

}

 

客户端:

    public static void main(String[] args) {

       // 创建客户端socket服务。

       Socket s = null;

       try {

            s = new Socket("localhost", 12345);

           // 创建键盘读取流,为了提高效率加入缓冲区。

           BufferedReader in = new BufferedReader(new InputStreamReader(

                  System.in));

           // 获取socket的输出流。

           BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s

                  .getOutputStream()));

           // 获取socket的输入流。

           BufferedReader br = new BufferedReader(new InputStreamReader(s

                  .getInputStream()));

           // 读取键盘数据,并把它写入到Socket流中。

           String line = null;

           while ((line = in.readLine()) != null) {

              if (line.equals("886"))

                  break;

              out.write(line);

              out.newLine();

              out.flush();

//            readLine是阻塞式的方法,没数据的时候就等。在等着socket中的数据,只是时间很短暂。

              String data = br.readLine();

              System.out.println("server:"+data);

           }

           in.close();

       } catch (UnknownHostException e) {

           e.printStackTrace();

       } catch (IOException e) {

           e.printStackTrace();

       }finally{

           if(s!=null)

              try {

                  s.close();

              } catch (IOException e) {

                  e.printStackTrace();

              }

       }

    }

3TCP上传图片

package net;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.net.UnknownHostException;

 

/**

 * 1,建立服务端点。 2,从客户端读取图片数据 3,将读取的数据写入到Scoket 4,关闭资源

 */

public class UploadPic {

    public static void main(String[] args) {

       try {

//         创建socket服务端

           Socket s = new Socket("localhost", 12345);

 

           InputStream in = new FileInputStream("e:\\1.jpg");

           OutputStream out = s.getOutputStream();

           byte[] buf = new byte[1024];

           int len = 0;

           while ((len = in.read(buf)) != -1) {

              out.write(buf, 0, len);

           }

//         socket中写入结束标识。

           s.shutdownOutput();

//         从服务器端读取反馈来的数据。

           InputStream is = s.getInputStream();

           int len1 = is.read(buf);

           String str = new String(buf, 0,len1);

           System.out.println("server" + str);

       } catch (UnknownHostException e) {

           e.printStackTrace();

       } catch (IOException e) {

           e.printStackTrace();

       }

    }

}

 

/**

 * 1,建立服务器端,并指定端口。 2,获得客户端发来的socket对象。 3,socket对象中获取流,并从流中读取数据。 4,向客户端回送数据。

 * */

class ServerPic {

    public static void main(String[] args) {

       try {

           // 建立客户端,获取客户端发来的socket,并通过socket获取客户端上传来的数据。

           ServerSocket ss = new ServerSocket(12345);

           Socket s = ss.accept();

           InputStream is = s.getInputStream();

           // 从客户端读取数据并写入到服务器端的硬盘上。

           OutputStream out = new FileOutputStream("f:\\1.jpg");

           byte[] buf = new byte[1024];

           int len = 0;

           while ((len = is.read(buf)) != -1) {

              out.write(buf, 0, len);

           }

           // 向客户端回馈数据。

           PrintWriter p = new PrintWriter(s.getOutputStream());

           p.write("上传成功");

           p.flush();

//         关闭资源。

           ss.close();

           s.close();

           out.close();

           p.close();

 

       } catch (IOException e) {

           e.printStackTrace();

       }

    }

}

 

4.TCP并发上传。

package net;

 

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.net.UnknownHostException;

 

/*

 * 完成客户端的并发上传。

 * 1,首先考虑使用多线程技术。因为完成并发上传的话,服务器端只有在处理完当前请求的情况下,才能接收下一次请求。

 * 2,再考虑在客户端使用还是在服务器端使用。每当一个客户端发出一个请求,服务器端就开出一个线程来处理此次请求。

 * 应该在服务器端建立这么一个线程类,用来接收客户端发来的socket对象,并完成服务器端的基本操作。

 *

 * **/

public class ThreadUpload implements Runnable {

 

    private Socket s;

    ThreadUpload(Socket s){

       this.s = s;

    }

    @Override

    public void run() {

       try {

           // 建立客户端,获取客户端发来的socket,并通过socket获取客户端上传来的数据。

//         ServerSocket ss = new ServerSocket(12345);

//         Socket s = ss.accept();

           InputStream is = s.getInputStream();

           // 从客户端读取数据并写入到服务器端的硬盘上。

           OutputStream out = new FileOutputStream("f:\\1.jpg");

           byte[] buf = new byte[1024];

           int len = 0;

           while ((len = is.read(buf)) != -1) {

              out.write(buf, 0, len);

           }

           // 向客户端回馈数据。

           PrintWriter p = new PrintWriter(s.getOutputStream());

           p.write("上传成功");

           p.flush();

           // 关闭资源。

//         ss.close();

           s.close();

           out.close();

           p.close();

 

        } catch (IOException e) {

           e.printStackTrace();

       }

    }

   

}

 

class UploadPic2 {

    public static void main(String[] args) {

       try {

           // 创建socket服务端

           Socket s = new Socket("localhost", 12345);

 

           InputStream in = new FileInputStream("e:\\1.jpg");

           OutputStream out = s.getOutputStream();

           byte[] buf = new byte[1024];

           int len = 0;

           while ((len = in.read(buf)) != -1) {

              out.write(buf, 0, len);

           }

           // socket中写入结束标识。

           s.shutdownOutput();

           // 从服务器端读取反馈来的数据。

           InputStream is = s.getInputStream();

           int len1 = is.read(buf);

           String str = new String(buf, 0, len1);

           System.out.println("server" + str);

       } catch (UnknownHostException e) {

           e.printStackTrace();

       } catch (IOException e) {

           e.printStackTrace();

       }

    }

}

 

/**

 * 1,建立服务器端,并指定端口。 2,获得客户端发来的socket对象。 3,socket对象中获取流,并从流中读取数据。 4,向客户端回送数据。

 * */

class ServerPic2 {

    public static void main(String[] args) {

       try {

           ServerSocket ss = new ServerSocket(12345);

           while(true){

              Socket s = ss.accept();//只要这句话执行完,其他的客户端请求就可以进来了。

              new Thread(new ThreadUpload(s)).start();

           }

       } catch (IOException e) {

           e.printStackTrace();

       }

    }

}

5.TCP用户并发登录。

    /*用户的模拟并发登陆:

 * 1,限制用户的登录次数为3次。如果用户输入超过三次还没有登录成功的话。那么会自动结束登录权限。

 * 2,服务器端的验证的登录次数最好也是3次。小于3次:客户端进行第3次登录时候,会再开启一个客户端的线程。

 * 大于3次:客户端三次登录没成功结束登录,请求都结束了,所以大于3次都是多余的了。

 * 3,在客户端定义一个类,读取键盘录入,并将录入信息发到服务器端。

 * 4,在服务器端定义一个线程类,用来接收客户端发来的请求,并处理客户端信息。实现并发。

 * */

6.模拟IE访问tomcat服务器。

/*1,如何获取浏览器向服务器发送的请求头。

 (1)通过浏览器向指定的主机端口(服务器)发送请求。

 (2)自定义服务器端,监听端口。

 (3)通过socket的读取流,获取请求信息。

 2,自定义浏览器

 (1)自定义浏览器客户端向服务器端发送请求。

 (2)请求的内容模拟浏览器的发送内容。

 (3)tomcat接收请求后,回馈响应信息和资源。

 (4)客户端获取信息并读取。

 */

    public static void main(String[] args) {

       try {

           Socket s = new Socket("localhost", 8080);

 

           PrintWriter out = new PrintWriter(s.getOutputStream(), true);

           // 模拟浏览器中的请求。

           out.println("GET /myweb/demo.html HTTP/1.1");

           out.println("Accept:*/*");

           out.println("Host: localhost:12345");

           out.println("Connection: closed");

           // 请求头下面必须要有一个空行。

           out.println();

           // 获取服务器反馈回来的信息。

           BufferedReader in = new BufferedReader(new InputStreamReader(s

                  .getInputStream()));

           String line = null;

           while ((line = in.readLine()) != null) {

              System.out.println(line);

           }

 

           s.close();

       } catch (UnknownHostException e) {

           e.printStackTrace();

       } catch (IOException e) {

           e.printStackTrace();

       }

7.URL-URLConnection

//URLURLConnection对象可以看作是应用层的连接对象。

public class URL_URLConnection {

    public static void main(String[] args) {

       try {

       URL url = new URL("http://localhost:8080/myweb/demo.html");

//底层封装了传输层的Socketconn可以解析服务器端回馈的响应头。浏览器的工作原理就是这样

//解析http头,获得资源内容。

       URLConnection conn =url.openConnection();

//底层获取了socket的读取流

       InputStream in = conn.getInputStream();

       byte[] buf = new byte[1024];

       int len = in.read(buf);

       System.out.println(new String(buf,0,len));

       } catch (MalformedURLException e) {

           e.printStackTrace();

       } catch (IOException e) {

           e.printStackTrace();

       }

    }

}

 

8.域名解析

先找本机的hosts文件,再通过dns往外找。

9.小知识点

SocketAddress表示InetAddressport

ServerSocket可以指定最大客户请求量。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics