Java网络编程之TCP网络通信

1      网络编程----TCPNo24

public class Server {

 

         public static void main(String[] args){

                   try {

                            ServerSocket ss =new ServerSocket(8888);//8888端口上建立ServerSocket

                            Socket s =ss.accept();//监听客户端的连接请求,一旦连接请求到达,建立连接,会返回一个服务器端的Socket

                            InputStream is =s.getInputStream();//获取这个Socket的输入流,用于读取客户端传来的信息

                            int b = is.read();//读一个字节

                            System.out.println(b);//打印

                            s.close();//关闭和客户端的连接

                            ss.close();//关闭ServerSocket,之后不再去监听端的连接请求

                   } catch (IOException e) {

                            // TODOAuto-generated catch block

                            e.printStackTrace();

                   }

         }

 

}

public class Client {

 

         public static void main(String[] args){

                   try {

                            Socket s = newSocket("127.0.0.1",8881);//向本机8888端口发送连接请求

                            OutputStream os =s.getOutputStream();//获取客户端Socket的输出流

                            os.write(100);//写一个字节100

                            s.close();//关闭套接字

                   } catch (IOException e) {

                            // TODOAuto-generated catch block

                            e.printStackTrace();

                   }

         }

 

}

网络

Protocol协议  就是一种格式、约定,网络两端的主机可以根据这个约定来进行信息的交互和传输

 

网络四层协议体系架构  TCP/IP

1、应用层  http、ftp

2、传输层  TCP、UDP

3、网络互联层  IP

4、主机到网络层

 

1.1    基本网络知识

1.1.1  Ip地址

InetAddress类的使用:

getByName(Stringhost):根据主机名获取IP对象

getHostAddress():获取主机地址

getHostName():获取主机名

getAllByName(Stringhost):获取主机名获取所有的IP对象

getLocalHost():获取本地主机对应的IP地址(127.0.0.1)

示例代码

//在Java中,使用InetAddress类描叙网络地址

                   InetAddress inetAddr = null;

                   //创建InetAddress对象

                   //在互联网上访问服务器有两种形式:1、ip地址   2、主机名(例如:http://www.baidu.com)

//               inetAddr =InetAddress.getByName("www.baidu.com");

                  

//               inetAddr =InetAddress.getByName("192.168.35.1");

//               inetAddr =InetAddress.getByName("192.168.81.144");

//               inetAddr = InetAddress.getByName("localhost");

                   //获取本机ip地址

                   inetAddr =InetAddress.getLocalHost();

                   //ip地址

                   String address =inetAddr.getHostAddress();

                   //主机名

                   String host =inetAddr.getHostName();

                   System.out.println(address+":"+host);

                  

                   InetAddress[] inetAddresses=InetAddress.getAllByName("www.baidu.com");

                   for (InetAddress inet :inetAddresses) {

                            System.out.println(inet.getHostAddress());

                   }

 

1.1.2  网络编程三要素

IP地址:网络中每台主机都必须有一个唯一的IP地址(网络中设备的标识)

端口:用于标识进程的逻辑地址,每个进程都有各自不同的标识, 有效端口0~65535,其中0-1024系统使用或保留端口

传输协议UDP---《将数据、源地址和目的地址封装在数据报包中;每个数据报的大小被限制在64K以内;不需要建立连接;是不可靠协议,速度快》

TCP----《建立连接,形成传输数据的通道;在连接中进行大数据传输;通过三次握手完成连接;必须建立连接;是可靠协议,效率较低》

 

通过三次握手完成连接:

【1. 客户端向服务器发送包含初始序列值的数据段,开启通信会话

2.      服务器发送包含确认值的数据段,其值等于收到的序列值加1,并加上其自身的同步序列值

3.      发送带确认值的客户端响应,其值等于接受的序列值加1.这便完成了整个建立连接的过程】

 

1.1.3  Socket(套接字)

1、Socket是为了网络服务而提供的一种机制;

2、套接字是两台机器间通信的端点;

3、网络通信其实就是Socket间的通信(所以网络编程又称为Socket编程);

4、Socket之间通过IO流来进行数据的传输(TCP);

5、Socket = IP地址 + 端口

TCP  Transmit Control Protocol传输控制协议

可以将IP报文进行包装、组织,有序可靠地传输到网络另一端

是基于连接的,两个主机在进行通信前必须先建立连接(三次握手)

 

(UDPUser Datagram protocol 用户数据报协议,不需要连接,信息传输会发生丢失)

协议都是跨语言、跨平台的

 

1.2    Java实现Tcp通信

如何用Java来进行TCP通信:

ServerSocket服务器套接字,用来监听客户端发送来的连接请求,一旦有客户端请求连接,就可以生成一个连接,并获取服务端这头的Socket

构造方法:ServerSocket(int port)在端口port上建立服务端套接字

Socketaccept() 监听客户端过来的连接请求,是一个阻塞方法,连接请求过来了,它就会返回建立的连接的服务端这头的套接字,这个套接字可以用来向客户端写或者从客户端读信息

 

Socket 套接字,就是网络上两台主机之间建立的连接的两个端点,可以通过它写信息,也可以读信息(套接字可以用于两台连接的主机之间进行通信,读写信息。)

 

1.2.1  服务端

一:服务端

getOutputStream()获取套接字输出流

write系列方法,使用和文件IO中差不多

getInputStream()获取套接字输入流

read系列方法

 

1.3    客户端

二:客户端

构造方法:Socket(String address,int port)参数为服务端的地址以及端口号,这样构建时就能发送一个连接请求到服务端,接下来这个创建出来的Socket对象就能用来和服务端通信

getOutputStream()获取套接字输出流

write系列方法,使用和文件IO中差不多

getInputStream()获取套接字输入流

read系列方法

 

getPort()获取端口号

getInetAddress()获取英特网地址对象(可以调用这个对象的getHostAddress()获取地址字符串)

 

另有一个4参构造方法Socket(String address,int port,InetAddress addr,int p)可以用第四个参数指定客户端的端口(2参构造方法的客户端端口随机分配)

 

1.4    实现及理论

Socket类:此类实现客户端套接字

ServerSocket:《此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。

PS:在创建Socket对象时,底层会自动创建一个客户端与服务端之间的通道,这个通道就是Socket流(网络IO流),Socket流既包含输入流,又包含输出流。》

使用步骤:

客户端:【《

1、 创建套接字对象(需要绑定指定的服务器ip地址和端口)

2、 通过IO流和服务端传输数据

3、 关闭Socket,释放资源》

服务端:【《

1、 创建服务端套接字对象(需要绑定端口,以便客户端连接)

2、 等待接收来自客户端的连接请求

3、 通过IO流与客户端传输数据

4、 关闭资源》

代码:

                                                                          Client.java客户端

public class Client {

 

   public static void main(String[] args) throws UnknownHostException, IOException {

      // tcp的客户端

      System.out.println("tcp客户端开启...");

      /*

       * 创建Socket对象,当执行这行代码的时候底层会自动和服务端建立连接(三次握手)

       * 如果连接建立不成功,就会抛出异常

       */

      //Socket socket = newSocket("127.0.0.1", 9999);

      Socket socket = new Socket("192.168.81.143", 9999);

      // 获取IO流对象,通过IO流对象可以实现与服务端的数据传输

      // socket.getInputStream();

      OutputStream os = socket.getOutputStream();

      os.write("来自tcp客户端的数据".getBytes());

      // 释放资源,断开与服务端的连接

      socket.close();

      System.out.println("tcp客户端关闭...");

   }

}

服务端:Server.java

publicclass Server {

 

         public static void main(String[] args)throws IOException {

                   // tcp的服务端

                   System.out.println("tcp服务端开启...");

                   // 创建服务端的套接字对象,用于响应来自客户端的连接请求

                   ServerSocket serverSocket =new ServerSocket(9999);

                   // 等待接收来自客户端的连接请求,连接成功后会返回与客户端对应的Socket对象

                   Socket socket =serverSocket.accept(); // 阻塞式方法

                   // 获取客户端的ip地址

                   String ip =socket.getInetAddress().getHostAddress();

                   System.out.println("与" + ip + "建立连接");

                   InputStream is =socket.getInputStream();

                   // socket.getOutputStream();

                   byte[] buf = new byte[1024];

                   int length = is.read(buf);

                   System.out.println(ip +":" + new String(buf, 0, length));

                   // socket.close();

                   // 释放资源,关闭服务端的套接字,会断开所有的客户端连接

                   serverSocket.close();

                   System.out.println("tcp服务端关闭");

         }

 

}

 

 

1.5    不间断发送消息到服务器

publicclass Client {

         public static void main(String[] args)throws UnknownHostException,

                            IOException {

                   // tcp的客户端

                   System.out.println("tcp客户端开启...");

                   Socket socket = newSocket("192.168.81.143", 9999);

                   Scanner scanner = newScanner(System.in);

                   /*BufferedReader br = newBufferedReader(new InputStreamReader(

                                     socket.getInputStream()));*/

                   BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(

                                     socket.getOutputStream()));

                   for(;;){

                            String line =scanner.nextLine();

                            bw.write(line);

                            bw.newLine();

                            bw.flush();

                   }

//               socket.close();

//               System.out.println("tcp客户端关闭...");

         }

}

publicclass Server {

 

         public static void main(String[] args)throws IOException {

                   // TODO Auto-generated methodstub

                   // tcp服务端

                   System.out.println("TCP服务端开启.....");

                   ServerSocket serverSocket =new ServerSocket(9999);

                   Socket socket =serverSocket.accept(); // 阻塞式方法

                   String ip =socket.getInetAddress().getHostAddress();

                   System.out.println("与" + ip + "建立连接");

 

                   BufferedReader br = newBufferedReader(new InputStreamReader(

                                     socket.getInputStream()));

                   String line = null;

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

                            System.out.println(ip+"发送来:"+line);

                   }

                   serverSocket.close();

                   System.out.println("TCP服务端关闭.....");

         }

}

】    

 

1.6    TCP上传文件到服务器

publicclass Client {

 

         // TCP的客户端

         public static void main(String[] args)throws UnknownHostException,

                            IOException {

                   // TODO Auto-generated methodstub

                   System.out.println("TCP客户端开启.......");

                   Socket socket = newSocket("192.168.81.143", 9999);

                   // 将指定的文件上传到服务器

                   // 一边读取文件数据,一边向服务器端写出数据

                   BufferedInputStream bis = newBufferedInputStream(new FileInputStream(

                                     "g:\\extras下文件.rar"));

                   BufferedOutputStream bos =new BufferedOutputStream(socket.getOutputStream());

                   int b=0;

                   while((b=bis.read())!=-1){

                            bos.write(b);

                   }

                   bos.close();

                   bis.close();

                   socket.close();

                   System.out.println("TCP客户端关闭.......");

         }

}

publicclass Server {

 

         public static void main(String[] args)throws IOException {

                   // TODO Auto-generated methodstub

                   System.out.println("tcp服务端开启....");

 

                   ServerSocket serverSocket =new ServerSocket(9999);

                   Socket socket =serverSocket.accept();

                   String clientName =socket.getInetAddress().getHostName();

                   BufferedInputStream bis = newBufferedInputStream(

                                     socket.getInputStream());

                   BufferedOutputStream bos =new BufferedOutputStream(

                                     newFileOutputStream("g:\\" + clientName + ".rar"));

                   int b = 0;

                   while((b =bis.read()) !=-1){

                            bos.write(b);

                   }

                   bos.close();

                   bis.close();

                   System.out.println("tcp服务端关闭...");

         }

}

 

1.7    多用户连接与数据发送

publicclass Client {

 

         public static void main(String[] args)throws UnknownHostException,

                            IOException {

                   // TODO Auto-generated methodstub

                   System.out.println("客户端开启./...");

                   Socket socket = newSocket("192.168.81.144", 6001);

                   System.out.println("成功与服务器建立连接....");

                   // 将键盘录入的数据传输到服务器

                   BufferedReader br = newBufferedReader(new InputStreamReader(System.in));

                   BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(

                                     socket.getOutputStream()));

                   //读一行写一行

                   String line = null;   //接收从键盘录入的数据

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

                            bw.write(line);

                            bw.newLine();

                            bw.flush();

                   }

                   bw.close();

                   br.close();

                   socket.close();                 

                   System.out.println("客户端关闭.....");

         }

}

//客户端响应线程

publicclass ClientEchoThread extends Thread {

         //客户端对应的Socket对象(每个客户端都有自己所对应的Socket对象)

         private Socket socket;

         private String ip;

        

         public ClientEchoThread(Socket socket){

                   this.socket = socket;

                   ip =socket.getInetAddress().getHostAddress();

         }

         //在线程中执行客户端的响应

         @Override

         public void run() {

                   System.out.println("建立与"+ip+"的连接");

                   BufferedReader br =null;

                   try {

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

                            //读取来自客户端的数据

                            String line = null;

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

                                     System.out.println(ip+":"+line);

                            }

                   } catch (IOException e) {

                            // TODOAuto-generated catch block

                            e.printStackTrace();

                   }finally{

                            if(br != null){

                                     try {

                                               br.close();

                                               br= null;

                                     } catch(IOException e) {

                                               //TODO Auto-generated catch block

                                               e.printStackTrace();

                                     }

                            }

                            if(socket != null){

                                     try {

                                               socket.close();

                                               socket= null;

                                     } catch(IOException e) {

                                               //TODO Auto-generated catch block

                                               e.printStackTrace();

                                     }

                            }

                   }

         }

}

/**

 *开启几个线程?

 *     有几个客户端就有几个线程

 *什么时候开线程?

 *     一旦有了新的客户端,就需要开启一个新的线程

 *线程中应该包含哪些代码?

 *     响应客户端的请求

 */

publicclass Server {

 

         public static void main(String[] args)throws IOException {

                   // TODO Auto-generated methodstub

                   System.out.println("服务端开启....");

            ServerSocket serverSocket = new ServerSocket(6001);

            //接收来自客户端的连接请求

            //阻塞式方法,一旦有新的客户端连接,就会返回一个客户端对应的Socket对象

            //作为客户端,应该不停地去接受客户端的请求

            while(true){

                     Socket socket =serverSocket.accept();

                     newClientEchoThread(socket).start();

            }   

//        serverSocket.close();

//        System.out.println("服务端关闭....");

         }

}

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值