由于即时通讯同时要接受来及远程Socket实例的消息,和发送消息给远程Socket实例。因此要建立两个线程分别来持续接受远端发送来的消息,和持续监听本地的输入并将其发送远程客户端。
一、服务端代码
package com.net;
import java.net.*;
import java.io.*;
/**
* Description:
* 搭建一个服务端来与客户端进行即时通行
*
* @author Lee
* */
public class ServerDemo{
/**
* Description:
* 实现一个服务端实例,获取远程客户端实例即时通行
*
* */
public static void getClient(){
ServerSocket server = null;
Socket client = null;
try{
//以指定的端口实现一个Socket服务端实例
server = new ServerSocket(12000);
while(true){
//获取客户端实例
client = server.accept();
System.out.println("已连接上"+client.getInetAddress()+"客户端,"+client.getPort()+"端口");
//启动持续接受远程客户端消息,即输入流
new Accept("client",client).start();
//启动持续监控控制台输入,将其传送远程客户端
new Return("client",client).start();
}
}catch(IOException e){
e.printStackTrace();
}finally{
//关闭资源
try{
server.close();
client.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
getClient();
}
}
二、客户端代码
package com.net;
import java.net.*;
import java.io.*;
/**
* Description:
* 实现一个客户端与远程服务端进行即时通行
*
* @author Lee
* */
public class ClientDemo {
/**
* Description:
* 实现一个客户端与远程服务端进行即时通行
* */
public static void getServer(String ip,int port){
Socket server = new Socket();
try{
//连接远程服务端
server.connect(new InetSocketAddress(ip,port));
System.out.println("已连接上"+server.getInetAddress()+"服务端,"+server.getPort()+"端口");
//启动持续接受远程服务端的消息,即输入流
new Accept("client",server).start();
//启动持续监控控制台输入,将其传送远程服务端
new Return("client",server).start();
}catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
//此处应该改写为服务端的IP地址
getServer("192.168.20.15",12000);
}
}
三、接受消息线程代码
package com.net;
import java.net.*;
import java.io.*;
import java.util.Scanner;
/**
* Description:
* 实现持续监控远程Socket的消息,即输入流,并将其输出在控制台上
*
* */
public class Accept extends Thread{
Socket socket ;
/**
* Description:
* 默认构造器
* */
public Accept(){}
/**
* Description:
* 通过初试化Socket,name变量来构造Accept实例
*
* @param name 该远程Socket实例的名字
* @param socket Socket实例
* */
public Accept(String name,Socket socket){
this.setName(name);
this.socket = socket;
}
@Override
public void run(){
Scanner input = null;
try{
//获取远程Socket实例的输入流
input = new Scanner(socket.getInputStream());
//将输入流的内容输出之控制台上
while(input.hasNext()){
System.out.println(this.getName()+":"+input.next());
}
}catch(IOException e){
e.printStackTrace();
}finally{
//关闭资源
input.close();
}
}
}
四、发送消息线程
package com.net;
import java.net.*;
import java.io.*;
import java.util.Scanner;
/**
* Description:
* 持续地监控控制台上的输入,并将其发送给远程Socket实例
*
* @author Lee
* */
public class Return extends Thread{
Socket socket;
/**
* Description:
* 默认构造器
* */
public Return(){}
/**
* Description:
* 通过初试化Socket,name变量来构造Return实例
*
* @param name 该远程Socket实例的名字
* @param socket 远程Socket实例
* */
public Return(String name,Socket socket){
this.setName(name);
this.socket = socket;
}
@Override
public void run(){
PrintWriter output = null;
Scanner keyboard = null;
try{
//获取远程Socket实例的输出流
output = new PrintWriter(socket.getOutputStream());
//获取控制台的输入
keyboard = new Scanner(System.in);
//监控控制台上的输入,将其输出给输出流
while(keyboard.hasNext()){
output.println(keyboard.nextLine());
output.flush();
}
}catch(IOException e){
e.printStackTrace();
}finally{
//关闭资源
output.close();
}
}
}
我们可以用telnet连接一下服务端,连接成功!
也可以看到java控制台上,有关于客户端的IP地址和连接端口,可以试一下发送消息给远程客户端。
可以看到远程客户端已收到了消息