JAVA에는 TCP와 UDP의 두 가지 주요 네트워크 프로그래밍 모드가 있습니다. TCP는 인스턴트 통신에 속하며 UDP는 데이터 패킷을 통해 통신합니다. 보안 성능 측면에서는 TCP가 약간 더 좋습니다. 통신 과정에서 데이터 손실이 발생하기 쉽지 않습니다. 한 당사자가 중단되면 UDP 데이터 패킷 전송 중에 한 당사자가 중단되면 두 당사자 간의 통신이 종료됩니다. 중단되면 데이터 패킷이 손실될 수 있으며 전송된 데이터 패킷의 순서가 잘못될 수 있습니다. UDP는 TCP보다 조금 더 빠르지 않습니다. 데이터를 구문 분석하는 기능이 있으면 데이터 패킷이 계속해서 전송되고 피드백됩니다.
위는 TCP 프로토콜 통신에 대한 두 가지 클래스입니다.
서버 클래스:
package TCP; import java.io.*; import java.net.*; import javax.swing.*; public class Server { //服务器端的输入流 static BufferedReader br; //服务器端的输出流 static PrintStream ps; //服务器相关的界面组件 static JTextArea text; JFrame frame; public Server(){ //服务器端的界面的实例化 JFrame frame=new JFrame("服务器端"); text=new JTextArea(); JScrollPane scroll =new JScrollPane(text); frame.add(scroll); frame.setVisible(true); frame.setSize(300,400); //这里设置服务器端的文本框是不可编辑的 text.setEditable(false); } public static void main(String[] args) throws Exception{ new Server(); //生成服务器界面 //通过服务器端构造函数 ServerSocket(port) 实例化一个服务器端口 ServerSocket server=new ServerSocket(2000); text.append("监听2000端口"+"\n"); //实例化一个接受服务器数据的对象 Socket client=server.accept(); br =new BufferedReader(new InputStreamReader(client.getInputStream())); ps =new PrintStream(client.getOutputStream()); String msg; //如果输入流不为空,将接受到的信息打印到相应的文本框中并反馈回收到的信息 while ((msg =br.readLine())!=null) { text.append("服务器端收到:"+msg+"\n"); ps.println(msg); if(msg.equals("quit")) { text.append("客户端“2000”已退出!"+"\n"); text.append("服务器程序将退出!"); break; } } ps.close(); br.close(); client.close(); } }
클라이언트 클래스:
package TCP; import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; import java.net.*; public class Client implements ActionListener{ //这里有两个图形界面,一个是连接的frame,另一个和服务器通信的界面frame1 private JFrame frame; private JLabel adress; private JLabel port; JTextField adresstext; JTextField porttext; JButton connect; private JFrame frame1; private JLabel shuru; private JPanel panel1; private JPanel panel2; private JLabel jieshou; JButton send; static JTextArea shurukuang; static TextArea jieshoukuang; //从服务端接受的数据流 static BufferedReader br1; //从客户端输出的数据流 static PrintStream ps; //从通信界面中的输入框接受的数据流 static BufferedReader br2; static Socket client; //将输入框字符串转换为字符串流所需的字符串的输入流 static ByteArrayInputStream stringInputStream ; public Client() { //连接界面的实例化 frame=new JFrame(); adress=new JLabel("IP 地址"); port =new JLabel("端口号"); adresstext=new JTextField("127.0.0.1",10); porttext=new JTextField("2000",10); connect=new JButton("连接"); //连接界面的布局 frame.setLayout(new FlowLayout()); frame.add(adress); frame.add(adresstext); frame.add(port); frame.add(porttext); frame.add(connect); frame.setVisible(true); frame.setSize(200,150); connect.addActionListener(this); //通信界面的实例化 frame1=new JFrame(); shuru=new JLabel("请输入"); shurukuang=new JTextArea("请输入····",5,40); panel1=new JPanel(); panel1.add(shuru); panel1.add(shurukuang); panel1.setLayout(new FlowLayout()); send=new JButton("发送"); panel2=new JPanel(); jieshou=new JLabel("已接受"); jieshoukuang=new TextArea(8,60); jieshoukuang.setEditable(false); panel2.add(jieshou); panel2.add(jieshoukuang); panel2.setLayout(new FlowLayout()); frame1.setLayout(new FlowLayout()); //通信界面都的布局 frame1.add(BorderLayout.NORTH,panel1); frame1.add(send); frame1.add(BorderLayout.SOUTH,panel2); //连接时通信界面是处于看不到的 frame1.setVisible(false); frame1.setSize(500,350); send.addActionListener(this); } //两个界面当中都有相应的按钮时间,为相应的时间添加动作 public void actionPerformed(ActionEvent e) { if(e.getSource()==connect){ try { //当触发连接按钮时,实例化一个客户端 client=new Socket("127.0.0.1",2000); //隐藏连接界面,显示通信界面 frame.setVisible(false); frame1.setVisible(true); jieshoukuang.append("已经连接上服务器!"+"\n"); } catch (IOException e1){ System.out.println("链接失败!"); e1.printStackTrace(); } } //通信界面中的发送按钮相应的时间处理 if(e.getSource()==send){ //将输入框中的字符串转换为字符串流 stringInputStream = new ByteArrayInputStream((shurukuang.getText()).getBytes()); br2 =new BufferedReader(new InputStreamReader(stringInputStream)); String msg; try{ while((msg=br2.readLine())!=null){ ps.println(msg); //将输入框中的内容发送给服务器端 jieshoukuang.append("向服务器发送:"+msg+"\n"); jieshoukuang.append("客户端接受相应:"+br1.readLine()+"\n"); if(msg.equals("quit")) { jieshoukuang.append("客户端将退出!"); br1.close(); ps.close(); client.close(); frame1.setVisible(false); break; } } }catch(IOException e2){ System.out.println("读输入框数据出错!"); } shurukuang.setText(""); } } public static void main(String[] args) throws IOException{ new Client(); //实例化连接界面 client=new Socket("127.0.0.1",2000); //从服务端接受的数据 br1=new BufferedReader(new InputStreamReader(client.getInputStream())); //从客户端输出的数据 ps =new PrintStream(client.getOutputStream()); } }
이 두 클래스를 작성한 후에도 여전히 몇 가지 질문이 있습니다.
1) 왜 main 함수를 static으로 수정해야 합니까?
2) 버퍼 객체인 BufferedReader를 직접 판단에 사용할 수 없는 이유는 무엇입니까? 읽은 데이터를 문자열에 할당하여 연산해야 하나요?
3) 연결 인터페이스의 연결 버튼 이벤트에서 클라이언트 개체를 인스턴스화했지만 기본 함수에서 client=new Socket("127.0.0.1",2000); NULLPOINTEXCEPTION 예외가 발생했다는 것을 이해하지 못합니까?
이 기사를 읽는 일부 전문가가 나에게 조언을 해주길 바랍니다. 나 또한 눈에 띄지 않는 구석에서 내 대답을 찾기 위해 끊임없이 "Think in Java"를 넘기고 있습니다.
Java TCP 네트워크 통신에 대한 더 자세한 예시와 관련 글은 PHP 중국어 홈페이지를 참고해주세요!