Scoket编程实现客户端服务端

好久以前的代码了今天拿来看看

基本实现了客户端和服务端的交互,客户端多线程,服务端单例加锁

当时写的时候没有注释,也没有解耦合(测试代码多线程的部分都堆在一起了),现在看来真是写的一团糟,好在基本功能实现按了,感觉服务端应该还可以封装一个有限队列这样比较好,比直接数组会好很多

贴代码

服务端

//服务器代码
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();
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值