聊天室小项目
这里我们使用TCP/IP和多线程来实现一个实验室的小项目
首先我们来写Server端的多线程任务:
这里我们主要做两个事情:等待从socket中读入信息,利用输入流对socket中写入信息:
package Task;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
public class ServerTask implements Runnable{
Socket socket;
//实现绑定
public ServerTask(Socket socket) {
// TODO Auto-generated constructor stub
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println( socket.getRemoteSocketAddress()+"进入了聊天室!" );
//输入流
try {
//字节流-》字符流-》缓冲流
BufferedReader bReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
/**
* 客户端信息不为空,那么服务器端可以回应
*/
String msg = bReader.readLine();
while ( msg != null) {
System.out.println(socket.getRemoteSocketAddress() + "说:" + msg);
//服务器端回应
//字节流转字符流
PrintWriter pWriter = new PrintWriter(socket.getOutputStream(),true );
Scanner scanner = new Scanner(System.in);
pWriter.println("服务器对"+socket.getRemoteSocketAddress()+"说:"+scanner.nextLine());
msg = bReader.readLine();
}
}catch (SocketException e) {
System.out.println( socket.getRemoteSocketAddress() + "退出聊天室" );
}catch (Exception e) {
// TODO: handle exception
}
}
}
随后是客户端的多线程任务:
实现的也是两个主要功能,向sockt中写入,并从sockt读出服务器发送的信息:
package Task;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientTask implements Runnable{
/**
* 与服务器端通信
*/
Socket socket;
public ClientTask(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
PrintWriter pWriter;
try {
//发送消息给服务器 输出流
//字节流转字符流
pWriter = new PrintWriter(socket.getOutputStream() );
Scanner scanner = new Scanner(System.in);
pWriter.println(scanner.nextLine());
pWriter.flush();
//接受服务器信息
//字节流-》字符流-》缓冲流
BufferedReader bReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("服务器说:"+bReader.readLine());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
最后我们从上面来实现客户端和服务端的逻辑:
客户端:
package Task;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.sound.sampled.Port;
public class ChatClinet {
/**
* 客户端
*/
public static void main(String[] args) {
//连接服务器,端口为服务器的启动端口,地址为服务器的IP地址
try {
//产生了随机的端口
Socket socket = new Socket( "127.0.0.1" ,8888);
Thread thread = new Thread( new ClientTask(socket));
thread.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务端:
package Task;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatServer {
/**
* 服务器端
* @param args
*/
public static void main(String[] args) {
//在端口8888上创建服务器连接
try {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器创建成功!");
//监听等待连接,一旦连接上,就会返回一个socket,是一个阻塞
while (true) {
//监听等待连接,程序阻塞
Socket socket = serverSocket.accept();
//只要成功连接,就启动一个线程
Thread thread = new Thread( new ServerTask(socket) );
thread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}