• 计算机网络介绍,TCP协议,Socket网络编程


    转载 自  http://blog.51cto.com/13501268/2092179

     Scoket(套接字)

    1. 两个应用程序可以通过一个双向的网络通信连接实现数据交换,这个双  向链接的一端称为一个Scoket

    2. Scoket可以看成两个程序进行通讯连接 中的一个端点,一个程序将一个  信息写入Scoket中,该Scoket将这段信息发送给另外一个Scoket中,  使这段信息能传送到其他程序中

    3. Scoket通常用来实现client-server(客户端—服务端)连接,建立连接时  所需要的寻址信息为远程计算机的IP地址和端口号(Port  Number

    4. 网络编程的四个基本步骤

    (1)创建scoket;

    (2)打开连接到scoket的输入输出流/输出流(通过Scoket的   getInputStream()getOutputStream());

    (3)按照一定的协议对scoket进行读写/写操作;

    (4)关闭scoket;

    5. 基于TCP协议的Scoket编程

    (1)基于TCP协议的scoket的网络通信

    <1>用来实现双向安全连接网络通信

    <2>TCP Scoket通常用来实现client-server连接,建立连接时所     需要的寻址信息为远程计算机的IP地址和端口号(Port      Number

    (2) TCP Scoket通信模型:进行网络通信时,Socket需要借助数据流来完成数据的传递工作

    图片1.png

    6.TCP通信原理

    图片2.png

    例1. (实现服务端与客户端连接)

    建立服务端:

    package scoket;

     

    import java.io.*;

    import java.net.*;

     

    public class Server {

    /* 编写服务器

     */

        public static void main(String[] args) {

            ServerSocket server=null;

            Socket socket=null;

            OutputStream out=null;

            try {

                server=new ServerSocket(9999);//创建服务器,并规定端口号为9999

                System.out.println("等待服务器连接..");

                socket=server.accept();//监听服务器连接,连接之前一直阻塞

                out=socket.getOutputStream();//获取Socket输出流,用来与他连接的服务器写入

                out.write("你好,Socket编程!!!".getBytes());//向输出流中写入内容,用getBytes()转化为字节数组

                System.out.println("发送成功...");

            } catch (IOException e) {

                e.printStackTrace();

            }finally{

            try {

                server.close();//关闭服务器

                socket.close();//关闭socket

            } catch (IOException e) {

                e.printStackTrace();

            }

            

            }

        

         

        }

     

    }

    建立客户端:

    package scoket;

     

    import java.io.*;

    import java.net.*;

     

    /*

     * 编写客户端

     */

    public class Client {

        public static void main(String[] args){

            Socket socket=null;

            InputStream input=null;

                try {

                    socket=new Socket("localhost",9999);//连接到服务器,localhost本机

                    input=socket.getInputStream();//获取socket输入流,用于获取服务器发送的信息

                byte[]  b=new  byte[1024];//建立字节数组缓冲区

                    int len=input.read(b);//读取字节数组

                    System.out.println("获取到的服务器信息为:"+new String(b,0,len));//将获取到的信息转化为字符串

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

         

        }

        运行结果为(运行时先启动服务端再启动客户端):

        服务端:

        等待服务器连接..

        发送成功...

        客户端:

        获取到的服务器信息为:你好,Socket编程!!!

        2(将输入输出流进行装饰):

        服务端:

        package decorator;

         

        import java.io.*;

        import java.net.*;

         

        /*

         * 服务端

         */

        public class Server {

            public static void main(String[] args) {

                ServerSocket server=null;

                Socket socket=null;

                try {

                    server=new ServerSocket(9999);//创建服务端,并规定端口号

                    System.out.println("客户端开始连接...");

                    socket=server.accept();//监听客户端,连接之前 一直阻塞

                    PrintStream ps=new PrintStream(socket.getOutputStream());//获取socket输出流,并封装到PrintStream输出流中;

                    ps.println("通过PrintStream发送信息...");//利用println()向客户端发送信息

                    System.out.println("服务器信息发送完毕...");

                } catch (IOException e) {

                    e.printStackTrace();

                }finally{

                try {

                    server.close();//关闭服务器资源

                    socket.close();//关闭socket

                } catch (IOException e) {

                    e.printStackTrace();

                }

           }

        }

     

    }

    客户端:

    package decorator;

     

    import java.io.*;

    import java.net.*;

    /*

     * 客户端

     */

    public class Client {

        public static void main(String[] args){

            Socket socket=null;

            InputStream input=null;

            try {

                socket=new Socket("localhost", 9999);//创建客户端 ,并建立连接

                //socket输入流封装到BufferedReader

                BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));

                String str=br.readLine();//利用readLine()读取接收到的服务端信息

                System.out.println("客户端:"+str);

            } catch (Exception e) {

                e.printStackTrace();

            } finally{

            try {

                socket.close();//关闭socket资源

            } catch (IOException e) {

                e.printStackTrace();

            }

            }

        }

     

    }

    运行结果:

    客户端开始连接...

    服务器信息发送完毕...

    客户端:通过PrintStream发送信息...

    例2. (模仿反响机制echo

    服务端线程类:

    package echo;

     

    import java.io.BufferedReader;

    import java.io.IOException;

    import java.io.InputStreamReader;

    import java.io.PrintStream;

    import java.net.Socket;

    /*

     * 服务端线程类

     */

    public class ECHORunnable implements Runnable{

        private Socket socket;

        

        public ECHORunnable(Socket socket) {

            this.socket = socket;

        }

         

        @Override

        public void run() {

            try {

                //获取输入流,用于读取客户端信息,用BufferedReader包装

                BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));

                //获取输出流用于向客户端发送信息,用PrintStream包装

                PrintStream ps=new PrintStream(socket.getOutputStream());

                //与客户端不断交互,直到客户端说‘bye’时退出与客户端交互

                while(true){

                    String str=br.readLine();//读取客户端发送来胡信息

                    ps.println(str);

                    if(str.equals("bye")){

                        socket.close();

                        break;

                    }

                }

            } catch (IOException e) {

                e.printStackTrace();

            }    

        }

         

    }

     

    服务端:

    package echo;

    /*

     * 服务端

     */

    import java.io.IOException;

    import java.net.*;

     

    public class Server {

     

        public static void main(String[] args) {

            ServerSocket server=null;

            Socket socket=null;

            try {

                server=new ServerSocket(9999);//创建服务端并规定端口号为9999

                boolean flag=true;

                int count=0;

                while(flag){

                    count++;

                    System.out.println("服务器与第"+count+"位客户端连接.....");

                    socket=server.accept();//监听客户端连接

                    new Thread(new ECHORunnable(socket)).start();//开启服务端线程

                }

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

     

    }

    客户端:

    package echo;

     

    import java.io.BufferedReader;

    import java.io.IOException;

    import java.io.InputStreamReader;

    import java.io.PrintStream;

    import java.net.Socket;

    import java.net.UnknownHostException;

     

    /*

     * 客户端

     */

    public class Client {

     

        public static void main(String[] args) {

            BufferedReader keybr=new BufferedReader(new InputStreamReader(System.in));

            Socket socket=null;

            try {

                socket=new Socket("localhost",9999);//连接本地服务端

                PrintStream ps=new PrintStream(socket.getOutputStream());//获取输出流,用于向客户端发送信息

                BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));//获取输入流用于读取服务端返回胡信息

                while(true){

                    System.out.println("白雪公主:");

                    String revice=keybr.readLine();//读取键盘输入

                    ps.println(revice);//发送客户端信息

                    String str=br.readLine();//获取服务端信息

                    System.out.println("青蛙王子:"+str);

                    if("bye".equals(revice)){

                       socket.close();

                       break;

                       }

                    }

                } catch (Exception e) {

                e.printStackTrace();

                }

            

        }

     

    }

    运行结果:

    白雪公主:

    你好

    青蛙王子:你好

    白雪公主:

    你在干啥

    青蛙王子:你在干啥

    白雪公主:

    bye

    青蛙王子:bye

    例4C-S传图片):

    服务端线程类:

    package binary;

     

    import java.io.*;

    import java.net.Socket;

    // 上传线程类

    public class UploadRunnable implements Runnable{

     

        private Socket socket;

        public UploadRunnable(Socket socket){

          this.socket=socket;

        }

         

        @Override

        public void run() {

            OutputStream out=null;

             try {

            InputStream input=socket.getInputStream();   // 用此来接收客户端发来的内容

            String fileName=System.currentTimeMillis()+".jpg";

            out=new FileOutputStream("d:"+File.separator+"upload"+File.separator+fileName);   // 用来写入服务器中的输出流

            byte[] b=new byte[1024];

            int len=0;

            // 循环从客户端读,写入服务器端

            while((len=input.read(b))!=-1){

            out.write(b, 0, len);

            }

            System.out.println(Thread.currentThread().getName()+"写入成功!");

            } catch (IOException e) {

            e.printStackTrace();

            }finally{

            try {

            out.close();

            socket.close();

            } catch (IOException e) {

            e.printStackTrace();

            }

            }    

            }

         

        }

        服务端:

        package binary;

         

        import java.io.IOException;

        import java.net.*;

        // 服务端

        public class Server {

         

        public static void main(String[] args) {

                ServerSocket server=null;

                try {

        server=new ServerSocket(8888);

        int count=0;

        while(true){

        count++;

        System.out.println("等待第"+count+"位客户连接...");

        Socket socket=server.accept();  // 监听客户端连接,连接之前一直阻塞

        new Thread(new UploadRunnable(socket)).start();   // 启动线程,在线程中与客户端交互

        }

        } catch (IOException e) {

        e.printStackTrace();

        }

       }

     

    }

    客户端:

    package binary;

     

    import java.io.*;

    import java.net.*;

     

    public class Client {

     

    public static void main(String[] args) {

    Socket socket=null;

    InputStream input=null;

    try {

    socket=new Socket("localhost",8888);

    input=new FileInputStream("d:"+File.separator+"images"+File.separator+"bingfa.jpg");

    OutputStream out=socket.getOutputStream();  // 用来向服务端不断写入

    byte[] b=new byte[1024];

    int len=0;

    // 从客户端磁盘上读,不断写入服务端

    while((len=input.read(b))!=-1){

    out.write(b,0,len);

    }

    System.out.println("客户端上传成功!");

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    try {

    input.close();

    socket.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

     

    }

     

    }

  • 相关阅读:
    Ubuntu下使用Sysvinit实现自定义服务(简单研究)
    Linux初始化init系统-Sysvinit、Upstart、Systemd
    Ubuntu查看系统版本的方法
    Linux查看文件内容命令:more(转)
    Linux查看文件内容命令:less(转)
    Ubuntu 16.04下MySQL 5.7.18取消开机启动(解决无法使用Sysvinit(update-rc.d/sysv-rc-conf)脚本关闭)
    为什么说Ubuntu的运行级别为2
    Ubuntu 16.04开机进入命令行(tty1)+分辨率调节+字体颜色设置+中文乱码解决(解决虚拟终端Ctrl+Alt+F1分辨率太大)
    Linux运行级别研究(转)
    Linux服务管理(Ubuntu服务管理工具sysv-rc-conf)(转)
  • 原文地址:https://www.cnblogs.com/kwaitfort/p/9130145.html
Copyright © 2020-2023  润新知