开发一个基于TCP协议的网络聊天室。(项目目录结构截图贴到答案框。测试时要求启动两个客户端,每个客户端至少发一次言
目录:
multiclient.java
package TCP;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class multiclient {
public multiclient(){
String hostName = "";
int portNumber = 7;
try {
//获得客户端的端口名,端口值
Socket echoSocket = new Socket(hostName, portNumber);
//输入信息
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
//读取信息
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
//获得本客户端口号名,端口值
System.out.println("客户端:"+echoSocket.getLocalAddress().getHostName()+":"+echoSocket.getLocalPort());
new Thread(new Runnable(){
@Override
public void run() {
String userInput;
try {
while (( userInput = stdIn.readLine()) != null) {
out.println(userInput);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(1);
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
String receiveStr;
try {
while ((receiveStr = in.readLine()) != null) {
System.out.println("发出信息为: " + receiveStr);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(1);
}
}
}).start();
} catch (UnknownHostException e) {
e.printStackTrace();
System.out.println("捕获异常信息为:"+e);
} catch (IOException e) {
e.printStackTrace();
System.out.println("捕获异常信息为:"+e);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new multiclient();
}
}
multiserver.java
package TCP;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class multiserver {
ServerSocket serverSocket;
List<Socket> clients = new ArrayList<Socket>();
public multiserver() {
try {
System.out.println("服务器启动成功!");
serverSocket = new ServerSocket(7);
System.out.println("绑定的端口号为:"+serverSocket.getLocalPort());
while (true) {
Socket clientSocket = serverSocket.accept();
clients.add(clientSocket);
//使用线程
new multithread(clientSocket, clients).start();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("端口启动失败!");
System.out.println("捕获异常为:"+e);
}
}
public static void main(String[] args) {
new multiserver();
}
}
multithread.java
package TCP;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.List;
//服务器端使用的线程
public class multithread extends Thread {
Socket currentclient;// 连接到当前客户端的Socket
List<Socket> clients;// 连接到所有客户端的Socket
String clientHostname;// 当前客户端的IP地址
int clientPort;// 当前客户端的端口号
// 构造方法,参数是连接当前客户端的Socket和连接到所有客户端的Socket列表
public multithread(Socket currentclient, List<Socket> clients) {
super();
this.currentclient = currentclient;
this.clients = clients;
}
@Override
public void run() {// 线程的执行主体
// 接收来自当前客户端的信息,转发给列表中的所有客户端
// 获取当前客户端的地址
InetSocketAddress clientAddress = (InetSocketAddress)
currentclient.getRemoteSocketAddress();
// 获取客户端IP地址
clientHostname = clientAddress.getHostName();
// 获取客户端的端口号
clientPort = clientAddress.getPort();
System.out.println("第" + clients.size() + "个客户端:"
+ clientHostname + ":" + clientPort + " 已连接");
try {
String inStr;
// 获取套接字输入流
BufferedReader in = new BufferedReader(new InputStreamReader(currentclient.getInputStream()));
// 用in对象接收来自当前客户端的信息
while ((inStr = in.readLine()) != null) {
System.out.println(inStr + "。 来自" + clientHostname + ":" + clientPort + "");
// 用循环使用列表中的Socket把接收的信息再发出去(输出)
for (Socket client : clients) {
if (client != null) {
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println(inStr + "。 来自" + clientHostname + ":" + clientPort + "");
}
}
}
} catch (IOException e) {
// 当客户端关闭连接,服务器端无法发送接收数据发生异常
System.err.println(clientHostname + ":" + clientPort + "退出了。");
//e.printStackTrace();
}
}
}