Java 简单TCP通信

Java中的TCP主要涉及ServerSocket和Socket两个类。前者被认为是服务端的一个实体,用于接受连接。后者则被认为是连接的一种封装,用于传输数据,类似于一个管道。

下面我结合Swing写一套客户端和服务端的程序。

程序启动后,客户端程序在窗口的文本框中输入内容。点击发送按钮时向服务器端发送文本框中的文本。服务器端收到信息后。反馈 ok。并在客户端窗口显示。
先看看程序界面:

服务端只有一个文本框,用来接收客户端发送过来的文本信息在这里插入图片描述
客户端,有一个文本框负责输入,一个负责从服务端接收反馈信息,一个发送按钮,点击后就会向服务端发送文本。在这里插入图片描述
下面上代码

客户端:

package swingTCP;
//导入相应的包
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import javax.swing.JLabel;
import java.awt.Font;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.awt.event.ActionEvent;

@SuppressWarnings("serial")
public class SwingClient extends JFrame {
	//界面组件
	private JPanel contentPane;
	private static JTextField sendText;
	private static JTextField textField;
	private JLabel returnText;
	private static JButton btnSend;
	private JLabel textLabel;
	
	//Socket对象
	public static Socket socket;
	//输出流
	public static OutputStream os;
	//输入流
	public static InputStream is ;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		//把界面窗口实现出来
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					SwingClient frame = new SwingClient();
					frame.setVisible(true);
					frame.setLocationRelativeTo(null);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});		
	}

	/**
	 * Create the frame.
	 */
	public SwingClient() {
		//设置界面标题
		setTitle("\u5BA2\u6237\u7AEF");
		try {
			//创建Scoket对象,并设置要访问的服务的IP和端口号
			//127.0.0.0表示本机地址,也可改为localhost
			socket = new Socket("127.0.0.1",987);
			 //返回此客户端的一个输出流
			os = socket.getOutputStream();		
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		sendText = new JTextField();
		sendText.setFont(new Font("宋体", Font.PLAIN, 14));
		sendText.setBounds(148, 93, 201, 31);
		contentPane.add(sendText);
		sendText.setColumns(10);
		
		textLabel = new JLabel("\u8F93\u5165\u6587\u672C\uFF1A");
		textLabel.setFont(new Font("宋体", Font.PLAIN, 14));
		textLabel.setBounds(60, 96, 78, 28);
		contentPane.add(textLabel);
		
		btnSend = new JButton("\u53D1\u9001");
		btnSend.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				//从文本框获取要发送的文本
				String send = sendText.getText();
				try {
					//通过流发送信息
					os.write(send.getBytes());
					//发送一个终结符,告诉服务器,已经发送完毕	
					socket.shutdownOutput();
					//以下是获取服务器回写的数据
					//返回此客户端的一个输入流
					is = socket.getInputStream();
					//将服务器回写的数据进行翻译,并打印在控制台
					byte[] bytes = new byte[1024];
					int len = 0;
					String rs="";
					while ((len = is.read(bytes)) != -1) {
						rs = rs+new String(bytes,0,len);
						//System.out.println(new String(bytes, 0, len));
					}
					if(rs!=""){
						//在文本框显示反馈信息
						textField.setText(rs);
					}
					else{
						textField.setText("无返回信息");
					}
				} catch (IOException e) {
					e.printStackTrace();
				}finally{
					//关闭流资源
					try {
						if(is!=null){
							is.close();
						}
						if(os!=null){
							os.close();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}		
			}
		});
		btnSend.setBounds(173, 212, 89, 39);
		contentPane.add(btnSend);
		
		textField = new JTextField();
		textField.setEditable(false);
		textField.setFont(new Font("宋体", Font.PLAIN, 14));
		textField.setColumns(10);
		textField.setBounds(148, 143, 201, 31);
		contentPane.add(textField);
		
		returnText = new JLabel("\u53CD\u9988\u4FE1\u606F");
		returnText.setFont(new Font("宋体", Font.PLAIN, 14));
		returnText.setBounds(60, 144, 78, 28);
		contentPane.add(returnText);
	}
}

服务端:

package swingTCP;
//导入相应的包
import java.awt.EventQueue;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;

@SuppressWarnings("serial")
public class SwingServer extends JFrame {
	//界面组件
	private JPanel contentPane;
	static JTextArea textArea = new JTextArea();
	//ServerSocket对象
	public static ServerSocket ss;
	//Socket对象
	public static Socket socket;
	//输入流
	public static InputStream is;
	//输出流
	public static OutputStream os;
	

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		/*SwingServer frame = new SwingServer();
		frame.setVisible(true);*/
		//把界面窗口实现
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					SwingServer frame = new SwingServer();
					frame.setVisible(true);
					frame.setLocationRelativeTo(null);
				} catch (Exception e) {
					e.printStackTrace();
				}	
			}
		});
		try {
			//创建ServerSocket类,并监听端口987
			ss = new ServerSocket(987);
			//界面的文本框显示文本
			SwingServer.textArea.setText("服务器准备就绪...");
		} catch (IOException e) {
			e.printStackTrace();
		}
		while(true){
			try {
				//获取连接
				socket = ss.accept();
				//调用Socket的getInputStream()方法,返回服务器输入流
				InputStream is = socket.getInputStream();
				//信息转成字节数组并输出在控制台
				byte[] bytes = new byte[1024];
				int len=0;
				String getText = "";
				while((len = is.read(bytes))!=-1){
					getText = getText+new String(bytes,0,len);
					//System.out.println(new String(bytes,0,len));
				}
				//在界面文本框显示收到的信息
				SwingServer.textArea.setText(getText);
				//服务器返回信息
				//调用Socket的getOutputStream()方法,返回服务器输出流
				os = socket.getOutputStream();
				String rs = "ok";
				//通过输出流反馈信息
				os.write(rs.getBytes());
				//关闭资源
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Create the frame.
	 */
	public SwingServer() {
		setTitle("\u670D\u52A1\u7AEF");
		
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		//textArea = new JTextArea();
		textArea.setEditable(false);
		textArea.setLineWrap(true);
		textArea.setBounds(74, 46, 270, 166);
		contentPane.add(textArea);		
	}
}

运行时要先运行服务端,不然程序会报异常,因为如果先运行客户端的话,没有相应的服务端可以供给客户端连接,就会因为找不到连接端口而报异常。

程序运行,在客户端输入文本,点击发送,即可。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值