好久以前的代码了今天拿来看看
基本实现了客户端和服务端的交互,客户端多线程,服务端单例加锁
当时写的时候没有注释,也没有解耦合(测试代码多线程的部分都堆在一起了),现在看来真是写的一团糟,好在基本功能实现按了,感觉服务端应该还可以封装一个有限队列这样比较好,比直接数组会好很多
贴代码
服务端
//服务器代码
package netCS;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServerTest implements Runnable {
public static int port = 8888;
private static TCPServerTest tcps = null;
public static ServerSocket serverSocket = null;
private static Socket[] sockets = new Socket[5];
private static int sflag = 0;
// private static void setFlag(int sflag) {
// TCPServerTest.sflag = sflag;
// }
private TCPServerTest() {
}
public static TCPServerTest getInstance(int num,Socket socket) {
if (tcps == null) {
synchronized(TCPServerTest.class) {
if(tcps == null) {
tcps = new TCPServerTest();
}
}
}
sockets[num] = socket;
return tcps;
}
public static void test() {
try {
serverSocket = new ServerSocket(port); // 端口号
System.out.println("服务器已启动,等待连接……");
Socket socket = null;
while(true) {
socket = serverSocket.accept(); // 等待客户端连接,线程阻塞等待直到客户端连接
System.out.println("客户端连接时A:================"+socket);
System.out.println("客户端已连接"); // 知道有客户端连接,accpet()会返回一个socket对象,,即客户端的连接
synchronized(TCPServerTest.class) {
Thread thread = new Thread(getInstance(TCPServerTest.sflag,socket));
System.out.println("线程开始前B:================"+sockets[TCPServerTest.sflag]);
TCPServerTest.sflag++;
System.out.println("TCPServerTest.sflag++后的值C"+ TCPServerTest.sflag);
thread.start();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
Socket socket = null;
System.out.println("线程开始D================"+socket);
synchronized(TCPServerTest.class) {
socket = sockets[TCPServerTest.sflag - 1];
}
System.out.println("线程开始E================"+socket);
PrintWriter pw = null;
BufferedReader br = null;
try {
pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "gbk")); // 装饰
br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "gbk"));
String line = null;
while ((line = br.readLine()) != null && !("QUIT".equals(line))) {
System.out.println("客户端发来消息:" + line);
pw.println("服务器回复消息:" + line);
pw.flush(); // 不加flush的话,内容会一直在缓冲区
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
br.close();
pw.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
test();
}
}
客户端
//客户端编程
package netCS;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TCPClientTest {
public static void test() throws Exception {
Socket socket = new Socket("127.0.0.150", 8888);// ip和端口号//127.0.0.150//192.168.0.150
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "gbk"));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "gbk"));
Scanner sc = new Scanner(System.in);
String line = null;
String msg = null;
System.out.println("请输入消息:(输入QUIT退出)");
while (!("QUIT".equals(msg = sc.nextLine())) ) {
System.out.println("请输入消息:(输入QUIT退出)");
pw.println(msg);
// pw.println(sc.nextLine());
pw.flush();
line =br.readLine();
System.out.println(line);
}
// pw.println("呵呵");
// while ((line = br.readLine()) != null ) {
// }
sc.close();
br.close();
pw.close();
socket.close();
}
public static void main(String[] args) throws Exception {
test();
}
}