计算机网络介绍,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();

}

}

 

}

 

}

猜你喜欢

转载自www.cnblogs.com/kwaitfort/p/9130145.html