客户端连接服务器

首先认识一下IP地址以及端口

IP地址被用来给Internet上的电脑一个编号。可以把一台电脑比作一部手机,那么IP地址相当于手机号码。
IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”。IP地址通常用“点分十进制”表示成(a,b,c,d)形式,其中a,b,c,d都是0~255之间的十进制整数。for example:192.168.1.5即是一个IP地址。

cmd中输入:ipconfig,即可显示IP地址。
通过端口号(port)来确定一台计算机中特定的网络程序。
一台机器的端口号可以在0~65535之间。下载文件,浏览网页,QQ聊天,这些程序对应不同的端口,信息传输到本机时,根据端口号来进行分类,用不同的程序来处理数据。

在cmd中输入:netstat -an,即可显示本机使用了哪些端口。
其中冒号后面的数字,即为端口号。
常用应用程序端口号:21–FTP协议,22–SSH安全登录,23–Telnet,25–SMTP协议,80–HTTP协议
0~1024的端口最好不要使用

认识TCP及UDP

TCP和UDP是两种信息传输协议,都能够进行网络通信。
TCP最重要的特点是面向连接,必须在服务器端和客户端连接上后才能通信,安全性较高。
UDP面向非连接,UDP是数据报,只负责传输信息,并不保证信息一定被收到,安全性不如TCP,但性能较好。

将TCP比喻成打电话,必须双方都拿起话机才能通话,并且连接需要保持通畅。
UDP比喻成寄信,寄信时,对方不知道有信过去,信寄到哪里,靠信封上的地址。

客户端和服务器

客户端(Client)/服务器(Server)是一种最常见的网络应用程序的运行模式,简称C/S。
以网络聊天软件为例,在聊天程序中,各个聊天的界面叫做客户端,客户端之间如果要相互聊天,则可以将信息先发送到服务器端,然后由服务器端转发。因此,客户端先要连接到服务器端。

客户端连接到服务器端,首先需要知道服务器端的IP地址,还要知道服务器端该程序的端口。
服务器必须首先打开这个端口,等待客户端的连接,俗称打开并监听某个端口。
在客户端,必须要做到以下工作:根据服务器IP,连接服务器的某个端口。

客户端连接到服务器

客户端连接到服务器端,首先需要知道服务器端的IP地址,还要知道服务器端该程序的端口。
服务器必须首先打开某个端口并监听,等待客户端的连接。客户端根据服务器IP,连接服务器的某个端口。
本例中,服务器为本机,打开并监听的端口号是8080。

服务器端打开并监听端口:
端口的监听是由java.net.ServerSocket进行管理的,这个类有很多构造函数,最常见的构造函数为:
public ServerSocket(int port) throws IOException
传入一个端口号,实例化ServerSocket,就已经打开了端口号并进行监听。
for example:

ServerSocket ss = new ServerSocket(8080);//监听服务器上的8080端口,并返回ServerSocket对象ss。

客户端连接到服务器某个端口:

客户端连接到服务器端的某个端口是由java.net.Socket进行管理的,这个类有很多构造函数,最常见的构造函数为:
public Socket(String host, int port) throws UnknownHostException, IOException
传入一个服务器IP地址和端口号,实例化Socket,就已经请求连接到该IP地址对应的服务器。
for example:

Socket socket = new Socket("192.168.32.1",8080);//连接服务器192.168.32.1上的8080端口,并返回连接Socket对象socket。

服务器怎么知道客户端连上来了?

既然客户端用Socket来向服务器请求连接,如果连接上之后,Socket对象自然成为连接的纽带。对于服务器端来说,就应该得到客户端的这个Socket对象,并以此为基础来进行通信。

怎样得到客户端的Socket对象?

服务器端实例化ServerSocket对象,监听端口。打开ServerSocket文档,会发现里面有一个重要函数:
public Socket accept() throws IOException
该函数返回一个Socket对象。
for example:

Socket socket = ss.accept();//得到客户端的Socket对象

accept函数是一个“死等函数”,如果没有客户端请求连接,它会一直等待并阻塞程序。一旦连接,阻塞被解除。

客户端和服务器端用Socket对象来进行通信,从Socket能否得到一些连接的基本信息呢?

打开Socket文档,会发现有如下函数:
public InetAddress getInetAddress()
返回Socket内连接客户端的地址,返回类型是java.net.InetAddress,
查找java.net.InetAddress文档,可以用以下方法得到IP地址:
public String getHostAddress()
返回 IP 地址字符串(以文本形式)。

运行结果:
先运行服务器代码,得到如下界面:
在这里插入图片描述
然后运行客户端代码,结果如下:
在这里插入图片描述
点击客户端界面的连接按钮:
在这里插入图片描述
再看服务器端的运行界面:
在这里插入图片描述
服务器端代码如下:

package chat1;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;

/**
 * 客户端程序
 * @author HP
 *
 */
public class Client extends JFrame implements ActionListener{
	private JButton btConnect = new JButton("连接");
	private Socket socket;
	
	//构造函数
	public Client() {
		super("客户端");
		this.setDefaultCloseOperation(3);
		this.setSize(500,100);
		this.setLocationRelativeTo(null);
		this.add(btConnect,BorderLayout.NORTH);//添加连接按钮组件
		btConnect.addActionListener(this);//*为按钮组件添加监听器*
		this.setVisible(true);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		try {
			socket = new Socket("192.168.32.1",8080);//连接服务器192.168.32.1(本地主机)上的8080端口0端口
			this.setTitle("恭喜您,已经连上");
		} catch (UnknownHostException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
	}
	
	public static void main(String[] args) {
		new Client();
	}
	
}

客户端代码如下:

package chat1;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JFrame;
/**
 * 服务器端代码
 * @author HP
 *
 */
public class Server extends JFrame {
	private ServerSocket ss;
	private Socket socket;
	
	//构造函数
	public Server() {
		super("服务器端,目前未见连接");
		this.setDefaultCloseOperation(3);
		this.setSize(500,100);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		
		//监听8080端口
		try {
			ss = new ServerSocket(8080);
			socket = ss.accept();//得到客户端的Socket对象
			String clientAddress = socket.getInetAddress().getHostAddress();//返回IP地址字符串
			this.setTitle("客户"+clientAddress+"连接");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public static void main(String[] args) {
		new Server();
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42882887/article/details/83213545