• TCP程序设计基础


    TCP网络程序设计是指用Socket类编写通信程序。利用TCP协议进行通信的两个应用程序是有主次之分的,一个称为服务器程序,另一个称为客户机程序。两者的功能和编写方法不大一样。服务器端与客户端的交互过程如图所示:
    在这里插入图片描述

    1. InetAddress

    java.net包中的InetAddress类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。InetAddress类的常用方法如下表所示:

    方法返回值说明
    getByName(String host)InetAddress获取与Host相对应的InetAddress对象
    getHostAddress()String获取InetAddress对象所包含的IP地址
    getHostName()String获取此IP地址的主机名
    getLocalHost()InetAddress返回本地主机的InetAddress对象

    代码示例如下:

    import java.net.*;
    
    public class Address{
    	public static void main(String[] args){
    		InetAddress ip;
    		try{
    			ip = InetAddress.getLocalHost();
    			String localname = ip.getHostName();
    			String localip = ip.getHostAddress();
    			System.out.println("本机名:" + localname);
    			System.out.println("本机IP地址:" + localip);
    		}catch(UnknownHostException e){
    			e.printStackTrace();
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2. ServerSocket

    java.net包中的ServerSocket类用于表示服务器套接字,其主要功能是等待来自网络上的”请求“,它可通过指定的端口来等待连接的套接字。服务器套接字一次可以与一个套接字连接。如果多台客户机同时提出连接请求,服务器套接字会将请求连接的客户机存入队列中,然后从中取出一个套接字,与服务器新建的套接字连接起来。若请求连接数大于最大容纳数,则多出的连接请求被拒绝。队列的默认大小是50。

    ServerSocket类的构造方法有如下几种:

    • ServerSocket():创建非绑定服务器套接字。
    • ServerSocket(int port):创建绑定到特定端口的服务器套接字。
    • ServerSocket(int port, int backlog):利用指定的backlog创建服务器套接字,并将其绑定到指定的本地端口号上
    • ServerSocket(int port, int backlog, InetAddress bindAddress):使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。这种情况适用于计算机上有多块网卡和多个IP地址的情况,用户可以明确规定ServerSocket在哪块网卡或哪个IP地址上等待客户的连接请求。

    ServerSocket类常用的方法如下表所示:

    方法返回值说明
    accept()Socket等待客户机的连接。若连接,则创建一个套接字
    isBound()boolean判断ServerSocket的绑定状态
    getInetAddressInetAddress返回此服务器套接字的本地地址
    isClosed()boolean返回服务器套接字的关闭状态
    close()void关闭服务器套接字
    bind(SocketAddress endpointvoid将ServerSocket绑定到特定地址(IP地址和端口号)
    getInetAddressint返回服务器套接字等待的端口号

    调用ServerSocket类的accept()方法,会返回一个和客户端Socket对象相连接的Socket对象。服务器端的Socket对象使用getOutputStream()方法获得的输出流,将指向客户端Socket对象使用getInputStream()方法获得的那个输出流。也就是说,当服务器向输出流写入信息时,客户端通过相应的输入流就能读取,反之亦然。

    accept()方法会阻滞线程的继续执行,直到接收到客户的呼叫。如果没有客户呼叫服务器,那么System.out.println(“连接中”)语句将不会执行。

    yu = server.accept();
    System.out.println("连接中")
    
    • 1
    • 2

    3. TCP网络程序

    明白了TCP程序工作的过程,就可以编写TCP服务器程序了。在网络编程中如果只要求客户机向服务器发送消息,不要求服务器向客户机发送消息,称为单向通信。客户机套接字和服务器套接字连接成功后,客户机通过输出流发送数据,服务器则通过输入流接收数据。下面是简单的单向通信的实例。

    TCP服务器程序:

    import java.io.*;
    import java.net.*;
    
    public class MyTcp{
    	private BufferedReader reader;
    	private ServerSocket server;
    	private Socket socket;
    	void getserver(){
    		try{
    			server = new ServerSocket(8998);
    			System.out.println("服务器套接字已经创建成功")
    			while(true){
    				System.out.println("等待客户机的连接");
    				socket = server.accept();
    				reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    				getClientMessage();
    			}
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    	}
    	private void getClientMessage(){
    		try{
    			while(true){
    				System.out.println("客户机:"+reader.readLine();)
    			}
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		try{
    			if(reader != null){
    				reader.close()
    			}
    			if(reader != null){
    				socket.close()
    			}
    		}catch(IOException e){
    			e.printStackTrace();
    		}
    	}
    	public static void main(String[] args){
    		MyTcp tcp = new MyTcp();
    		tcp.getserver();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    客户端程序:

    package com.lzw;
    
    public class MyClien extends JFrame{
    	private PrintWriter writer;
    	Socket socket;
    	private JTextArea ta = new JTextArea();
    	private JTextField tf = new JTextField();
    	Container cc;
    	
    	public MyClien(String title){
    		super(title); //调用父类的构造方法
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		cc = this.getContentPane();
    		final JScrollPane scrollPane = new JScrollPane();
    		scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
    		getContentPane().add(scrollPane, BorderLayout.CENTER);
    		scrollPane.setViewportView(ta);
    		cc.add(tf,"South"); //将文本框放在窗体的下部
    		tf.addActionListener(new ActionLisener(){
    			//绑定事件
    			public void actionPerformed(ActionEvent e){
    				writer.println(tf.getText()); //将文本框中的信息写入流
    				ta.append(tf.getText() + '\n'); //将文本框中的信息显示在文本域
    				ta.setSelectionEnd(ta.getText().length());
    				tf.setText(""); //将文本框清空
    			}
    		});
    	}
    	private void connect(){
    		ta.append("尝试连接\n");
    		try{
    			socket = new Socket("127.0.0.1", 8998);
    			writer = new PrintWriter(socket.getOutputStream(),true);
    			ta.append("完成连接\n")
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    	}
    	public static void main(String[] args){
    		MyClien = new MyClien("向服务器送数据");
    		clien.setSize(200,200); //设置窗体大小
    		clien.setVisible(true); //将窗体显示
    		clien.connect(); //调用连接方法
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
  • 相关阅读:
    SD卡笔记
    非递归方式实现二叉树四种遍历
    深入剖析 Python 最常用数据结构:列表(List) & 元组(Tuple)
    DFS与回溯专题:二叉树的最大深度
    【学习】目标检测中的anchor
    5.用户注册_表单验证——使用wtforms-tornado表单数据验证
    2022PMP项目管理认证考试报考指南(1)
    Python操作Jenkins API
    深入理解JVM-类加载与字节码技术
    JVM运行时数据区——程序计数器
  • 原文地址:https://blog.csdn.net/weixin_44860226/article/details/127902695