Java研究ノート(21)-ネットワークプログラミング(ソケット)、TCP、UDP、簡単なチャットプログラム

ネットワークプログラミング(ソケット)

跟网络相关的操作实质都是数据传输。
通过IO流在网络上实现数据传输。
	网络模型---物理层---数据链路层---网络层---传输层(TCP/UDP)---会话层---表示层---应用层
IP地址---确定主机在网络世界中的位置。
	分类 IPV4 四位0-255来组成 
		IPV6四位16进制的数
端口---用于和计算机外界进行数据交互的媒介。
端口号---端口的标记 0-65535来表示。
域名---域名可以和IP地址进行一一映射。

IPとポート

package com.hst.netio;
import java.net.InetSocketAddress;
/**
 * InetSocketAddress
 * 1代表IP
 * 1地址和端口号的类
 * @author Administrator
 *
 */
public class InetSocketAddressDemo {
    
    
 public static void main(String[] args) {
    
    
  //创建代表IP和端口号的类的对象
  InetSocketAddress is = new InetSocketAddress("www.baidu.com",8090);
  System.out.println(is.getAddress().toString());//IP地址
  System.out.println(is.getHostName().toString());//主机名
  System.out.println(is.getPort());//端口号
 }
}

UDPとTCP

UDPとTCPのプロセスは異なります

UDP:プロセスは速達のプロセスと似ていますが、独自の宅配便ポイント(ソケットオブジェクト)とパッケージ(データパケットオブジェクト)が必要です。パッケージにも独自のマーク(パッケージ自体、IPアドレス、およびオブジェクトのポートマーク)があります。パッケージのパッケージ化と送信のプロセスは、宅配便ポイント(ソケットオブジェクト)によって実行されます。

UDP

データレシーバー

package com.hst.netio;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
/**
 * 1接收发送端发送的内容
 * 1接收端要监听数据包的端口号
 * 1创建接收数据的数据包
 * 1端口是接收数据的链接
 * 1数据传输先发送
 * @author Administrator
 *
 */
public class UDPjieshouDemo {
    
    
 public static void main(String[] args) throws IOException {
    
    
  //创建套接字对象 相当于建立一个快递点 来接收寄送的快递 要接收寄送的快递 就要知道快递的编号 即监听端口号
  DatagramSocket ds = new DatagramSocket(9090);
  //创建接收数据的数据包
  //接收端要有字节来接收数据
  DatagramPacket dp = new DatagramPacket(new byte[1024],1024);
  ds.receive(dp);//接收数据
  ds.close();//关流
  //解析数据包
  System.out.println(dp.getAddress());
  System.out.println(dp.getPort());
  System.out.println(new String(dp.getData(),0,dp.getLength()));
 }
}

データ送信者

package com.hst.netio;
import java.io.IOException;
/**
 * 1基于IO流
 * 1传输数据时不会建立链接
 * 1不可靠的传输方式 不可靠 不安全
 * 1传输速度快
 * 1底层根据数据包进行数据的传输 数据包的最大值不能超过 64KB
 * 1适合传输的场景 直播 语音 视频等
 * 1DatagramSocket DatagramPacket
 * 1用于UDP
 * 0步骤
 * 1创建套接字对象   相当于是成立一个快递寄送点
 * 2创建数据包       相当于是打包一个包裹 要求有包裹的内容 包裹的寄送目的地 和寄送点 端口号可以作为包裹的标记 地址名是寄送地点
 * 3发送数据包       相当于是从快递点寄送包裹
 * 4关流
 * @author Administrator
 *
 */
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class UDPfasongDemo {
    
    
 public static void main(String[] args) throws SocketException {
    
    
  //创建套接字对象
  DatagramSocket ds = new DatagramSocket();
  //创建数据包
  //第一个参数要发送的数据
  //转换为字节数组 默认为字节流
  //可以传输的数据的字节个数
  //制定地址和端口号
  DatagramPacket dp = new DatagramPacket("hello".getBytes(),"hello".length(),new InetSocketAddress("localhost",9090));
  //发送数据包
  try {
    
    
   ds.send(dp);
  } catch (IOException e) {
    
    
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  ds.close();//关流
 }
    //
}

UDPに基づくシンプルなチャットプログラム

package com.hst.netio;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;
/**
 * 1用来建立一个微型的数据传输的聊天室
 * 1需要结合线程来实现
 * 1一直发送 一直接收
 * 1知道发送者和接收端
 * @author Administrator
 *
 */
public class MiniChatDemo {
    
    
 public static void main(String[] args) {
    
    
  new Thread(new ChatSentDemo(),"发送者").start();
  new Thread(new Receiv(),"接收者").start();
 }
}
//用来代表线程发送的类
class ChatSentDemo implements Runnable{
    
    
 //
 public synchronized void run() {
    
    
  //
   try {
    
    
    //创建套接字对象
    DatagramSocket ds = new DatagramSocket();
    Scanner sc = new Scanner(System.in);
    //
    while(true) {
    
    //一直发送的状态;
     byte[] data = sc.next().getBytes();
     //创建数据包
     DatagramPacket dp = new DatagramPacket(data,data.length,new InetSocketAddress("127.0.0.1",9091));
     ds.send(dp);
    }
   } catch (IOException e) {
    
    
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  //
 }
}
//代表线程接收的类
class Receiv implements Runnable {
    
    	
 public synchronized void run() {
    
    
  //创建套接字对象
  try {
    
    
   DatagramSocket ds = new DatagramSocket(9091);
   while(true) {
    
    
   DatagramPacket dp = new DatagramPacket(new byte[1024],1024);
   ds.receive(dp);
   System.out.println("收到来自"+dp.getAddress()+"的消息"+new String(dp.getData(),0,dp.getLength()));
   }
  } catch (IOException e) {
    
    
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

TCP:プロセスは有線電話をかけるのと似ています。まず、電話回線(ソケットオブジェクト)を確立する必要があります。電話回線リンクには2つの条件が必要です。相手の場所(IP)。唯一の一意の回線(ポート)。接続オブジェクトに付属するIOストリーム)電話をかけるときは、電話が鳴ったことを相手に通知する必要があります。

package com.hst.netio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import org.omg.CORBA.portable.OutputStream;
public class TCPServerDemo {
    
    
 public static void main(String[] args) throws IOException{
    
    
  //创建服务器端对象---监听端口
  //创建服务器端对象---监听端口
  ServerSocket ss= new ServerSocket(9092);//这是一个寄送站 
  //接受连接
  Socket s=ss.accept(); //阻塞
  //while(true);
  System. out .println(1);
  //接受客户端发送数据
  //获取自带的字节输入流
  InputStream is=s.getInputStream();
  //自建缓冲区
  byte[]bs= new byte[10];
  //
  int len=-1;
  while((len=is.read(bs))!=-1){
    
     //阻塞
  //输出每次读到的内容
  System. out .println( new String(bs,0,len));
  }
  //通知客户端数据已经接受完毕
  s.shutdownInput();
  //获取自带的字节输出流给客户端发送数据
  java.io.OutputStream os = s.getOutputStream();
  os.write( "你也好".getBytes());
  //通知客户端数据已经发生完毕
  s.shutdownOutput();
  //关流
  ss.close();
  }
}
package com.hst.netio;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import org.omg.CORBA.portable.OutputStream;
/**
 * 1基于io
 * 1可靠安全
 * 1传输速度慢
 * 1不根据数据包传输数据 没有大小限制
 * 1使用场景 聊天 文件 
 * @author Administrator
 *
 */
public class TCPClientDemo {
    
    
 public static void main(String[]args) throws IOException{
    
    
  //创建客户端对象
  Socket s = new Socket();//建立一个电话设备
  //建立连接---阻塞
  s.connect( new InetSocketAddress( "127.0.0.1",9092));//创建一条专属的线路 并链接特定用户的标记
  //while(true);
  //往服务器端发送数据
  //获取自带的字节输出流 默认往服务器端写数据
  java.io.OutputStream os = s.getOutputStream();//
  //通过自带的输出流写出数据
  os.write( "您好".getBytes()); //阻塞
  /*for(inti=0;i<=100000;i++){
  os.write("a".getBytes());
  System.out.println(i);
  }*/
  //通知服务器端数据已经写完
  s.shutdownOutput();//将信件内容发送出去 
  //接受服务器端发送的数据
  InputStream is=s.getInputStream();
  byte[] bs= new byte[10];
  int len=-1;
  while((len=is.read(bs))!=-1){
    
    
  System. out .println( new String(bs,0,len));
  }
  //通知服务器端数据已经接受完毕
  s.shutdownInput();//告诉服务器 收到回信
  //关流
  s.close();
  }
}

おすすめ

転載: blog.csdn.net/qq_42351519/article/details/111864110