java网络编程:9、基于TCP的socket编程(二)服务器端循环监听接收多个客户端_多线程服务器程序

417 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划· 6 月更文挑战」的第4天,点击查看活动详情

声明:本教程不收取任何费用,欢迎转载,尊重作者劳动成果,不得用于商业用途,侵权必究!!!

文章目录

一、核心代码编写

1、服务器端程序的编写

2、客户端程序的编写

3、测试打印输出

上篇讲了基于tcp的编程的一些基础知识,还写了一个简单的socket通信的代码,大家如需了解可参考 java网络编程:8、基于TCP的socket编程(一)简单的socket通信_一个客户端,这篇较上篇稍微深入点,本来上篇就要搞定的,因为是整理知识、整理代码,所以自己不希望博客篇幅太长,不方便以后自己的查阅,所以拖到这篇来写、来记录!

一、核心代码编写

服务器端循环监听接收多个客户端_多线程服务器程序

1、服务器端程序的编写

public class Myserver extends Thread{
	public static void main(String[] args) {
		server();
	}
	
	
	private Socket s;
	public Myserver(Socket s) {
		this.s = s;
	}
	
	
	@Override
	public void run() {
		try {
			// 可以利用套接字获取输出流、输入流
			OutputStream os = s.getOutputStream();
			InputStream is = s.getInputStream();
			os.write("Hello,welcome you,client!".getBytes());

			byte[] buf = new byte[100];

			int len = is.read(buf);

			// 将我们读取的数据打印出来
			System.out.println(new String(buf, 0, len));
			// 完成通信之后,我们可以将输出流、输入流、套接字、服务器端的套接字都关闭
			os.close();
			is.close();
			s.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}
	
	
	/**
	 * 服务器端程序的编写
	 */
	public static void server() {
		try {
			// 创建服务器端套接字,绑定到6000的端口上
			ServerSocket ss = new ServerSocket(6000);
			
			//当前为一个客户服务,要为多个客户同时服务加while循环监听客户端请求
			while (true) {
				Socket s = ss.accept();
				new Myserver(s).start(); 
			}
			//ss.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	
}

其中重要代码说明:

 利用输出流向客户端发送数据 

getBytes将字符串转换成字节数组

os.write("Hello,welcome you,client!".getBytes());

利用输入流从网络上读取数据 

建立字节数组

byte[] buf = new byte[100];

将数据读取到buf字节数组当中, 

它会返回实际读取的字节数

int len = is.read(buf);

调用accept方法就会阻塞,直到客户端有连接请求到来的时候。

 它会返回一个套接字,然后就可以利用这个套接字与客户端进行数据通信。

Socket s = ss.accept();

一旦有一个连接请求到来,接收连接请求,返回套接字。

然后创建启动一个新的线程,将套接字传递给线程,为客户端进行服务

Run执行完毕,当前线程也就终止了

new Myserver(s).start(); 

2、客户端程序的编写

/**
	 * 客户端程序的编写
	 */
	public static void client() {
		try {
			Socket s = new Socket(InetAddress.getByName("localhost"), 6000);
			// 可以利用套接字获取输出流、输入流
			OutputStream os = s.getOutputStream();
			InputStream is = s.getInputStream();
			//输入流向服务器端读取数据
			byte[] buf = new byte[100];
			int len = is.read(buf);
			System.out.println(new String(buf, 0, len));
			//输出流向服务器端发送数据
			os.write("Hello,this is zhangsan".getBytes());
			//完成通信之后,我们可以将输出流、输入流、套接字都关闭
			os.close();
			is.close();
			s.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

其中这句代码

Socket s = new Socket(InetAddress.getByName("localhost"), 6000);

// 创建一个客户端的套接字,指定一个ip地址和端口。 

// 让它连接到我们服务器端上,在这个端口上等待连接的服务器进程 

// ip地址:你可以指定主机名,或者指定ip地址,让它直接返回。 

// 我们在编写程序的时候,可能没有两台机器,没有关系,我们可以在一台机器上, 

// 让我们服务端程序和客户端程序,通过网络进行通信。 

// 那么我们可以获取本地的ip地址,它有三种方式:

 // InetAddress.getByName("localhost") 

// InetAddress.getByName("127.0.0.1")是我们本地的回路地址 

// InetAddress.getByName(null)它也可以返回本地的IP地址 

//那么这三种方式,即使这我们的机器上没有网卡,也没有关系。 

//那么作为一台pc机,它都会有一个"127.0.0.1"作为本地的一个回路地址,那么我们用这个地址, 就可以测试我们的网络程序。 

 //注:你在客户端发送连接请求的端口号,和服务器端等待连接的端口号一定要一致。 

//这就好像你打电话一样,那么我的分机号是6000,那么你打过来的时候你转这个分机号,你也要转6000 

//才能够和我进行通信,你不能说你随便转个分机号,你想转5000和我进行通信,那是不可能的。

3、测试打印输出

首先我们运行服务器端程序,因为加了循环所以服务器一直在监听

运行客户端程序,它连上服务器端程序并发送消息,服务器端收到消息,如下图:

同时服务器端,给客户端 “zhangsan” 发送消息,如下图:

然后我们模拟多个客户端:

把客户端程序语句 os.write("Hello,this is zhangsan".getBytes()); 改成 os.write("Hello,this is lisi".getBytes());

再次运行客户端程序,同样可以连接到服务器端程序并发送消息,服务器端收到消息,如下图:

同时服务器端,给客户端 “lisi” 发送消息,如下图: