【java】【soversocket】网络编程,局域网通信

socket编程

1、准备工作

eclipse java 

2、java支持网络编程,并且已经将其封装在java.net下,主要两个类,ServerSocket作为服务器端监听启动端口(1024-65535,0-1024系统占用),与客户端连接通信的类。Socket(套接字)表示一个连接,可以使用构造器Socket(String ip,int port)连接服务器,并且与之通信的类。

3、这里学习的是单服务器单个客户端的通信,多客服端单服务器的通信。

对于单对单的通信来说,服务器通过输入流接收到了客服端的请求之后,将消息处理,通过输出流发送到客服端,所以服务器端只需要一个监听客户端输入的线程,服务器如果需要单独一个线程监听服务器输入(如想通过Console控制服务器的启停),则应再启动一个线程。客服端通过Socket构造器连接服务器之后,获取IO流,应该启动两个线程一个监听服务器输入,一个监听客服端输入(如键盘打印)。

对于多对单来说,客服端差不多,但是在服务器端应该一直监听客服端的连接,并且每个连接都需要被监听,同时将每个连接放入一个map集合里面。当客服端想与客服端通信时,就可以同个map取得连接,获取输出流,将消息发送到想通信的客户端

4、注意:socket的关闭,会导致相对应的socket的关闭,socket关闭时同时会将输入输出流关系,向输出流输出数据时,一定要加上结束标志(pw.println(),pw.print(msg+"\r\n")),否则对应的输入流在read或者readline会出现异常。

5、代码

客户端

public class Client implements Runnable{
	//1、创建客户端Socket,指定服务器地址和端口
	private static Socket socket =null;
	private static boolean isStop = false;
	static {
		try {
			socket = new Socket(InetAddress.getLocalHost(),10086);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	// 搭建客户端
    public static void main(String[] args) throws IOException {//客户端
    	
    	//2、获取输出流,向服务器端发送信息
    	PrintWriter pw =new PrintWriter(socket.getOutputStream());//将输出流包装成打印流
    	
    	BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in));
    	Thread t = new Thread(new Client());
    	t.start();
    	while(true) {
    		String info = keyIn.readLine();
    		if("end".equals(info)) {
    			isStop = true;
    			pw.println("end");
    	    	pw.flush();
    			break;
    		}else {
    			pw.write(info + System.getProperty("line.separator"));
    	    	pw.flush();
    		}
    	}
    	//socket.shutdownOutput();

    	//4、关闭资源
    	socket.close();
    	}
	@Override
	public void run() {
		//3、获取输入流,并读取服务器端的响应信息
    	BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			while(true){
	    		String info=br.readLine();
	    		System.out.println("我是客户端,服务器说:"+info);
	    		if(isStop) {
	    			break;
	    		}
	    	}
	    	
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    	
	}
}
服务器

public class SocketService {
	public static void main(String[] args) throws Exception {
		
		//1、创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
		ServerSocket serverSocket =new ServerSocket(10086);//1024-65535的某个端口
		//2、调用accept()方法开始监听,等待客户端的连接,进程阻塞
		Socket socket = serverSocket.accept();
		//3、获取输入流,并读取客户端信息
		BufferedReader br =new BufferedReader(new InputStreamReader(socket.getInputStream()));
		//4、获取输出流,响应客户端的请求
		PrintWriter pw = new PrintWriter(socket.getOutputStream());
		
		while(true){
			String info=br.readLine();
			//处理消息
			System.out.println("我是服务器,客户端说:"+info);
			//返回客户端消息
			pw.println("欢迎您!");
			//
			pw.flush();
			if("end".equals(info)) {
				break;
			}
		}
		//socket.shutdownInput();//关闭输入流


		//5、关闭资源
		//pw.close();
		//br.close();
		socket.close();
		serverSocket.close();
	}
}

多对单服务器端

public class MultiClientServer {
	private volatile static Map<String,Socket> socketes = new HashMap<>();
	private static boolean isStop = false;
	
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(10086);
		while (true) {
			Socket client = server.accept();
			BufferedReader in = new BufferedReader(new InputStreamReader(
					client.getInputStream()));
			PrintWriter out = new PrintWriter(client.getOutputStream(),true);
			out.println("please input username!");
			String name = in.readLine();
			socketes.put(name, client);
			SocketListener mc = new SocketListener(client);
			new Thread(mc,name).start();
			if(isStop) {
				break;
			}
		}
		server.close();
	}
	private static class SocketListener implements Runnable{
		private Socket client;
		private boolean isObjestStrean = false;
		public SocketListener(Socket so) {
			this.client = so;
		}
		public void run() {
			try {
				BufferedReader in = new BufferedReader(new InputStreamReader(
						client.getInputStream()));
				ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
				PrintWriter out = new PrintWriter(client.getOutputStream());
				//监听客户端输入
				while (true) {
					String str = "";
					//对象流处理
					if(isObjestStrean) {
						Object o = ois.readObject();
						MSG msg = null;
						if(o instanceof MSG) {
							msg = (MSG)o;
						}else {
							continue;
						}
						if(!msg.validate()) {
							continue;
						}
						//处理消息
						str = msg.getMsg();
						PrintWriter out2 = new PrintWriter(socketes.get(msg.getReciever()).getOutputStream(),true);
						out2.println(str);
					}else {
						//字符流
						str = in.readLine();
						System.out.println(str);
						out.println("has receive....");
						out.flush();
					}
					if (str.equals("end")) {
						isStop = true;
						break;
					}
				}
				client.close();
			} catch (IOException ex) {
				
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
			}
		}
	}
	public class MSG implements Serializable{
		private static final long serialVersionUID = 1L;
		private String sender;
		private String msg;
		private String reciever;
		public String getSender() {
			return sender;
		}
		public boolean validate() {
			return socketes.containsKey(reciever)&&socketes.containsKey(sender);
		}
		public void setSender(String sender) {
			this.sender = sender;
		}
		public String getMsg() {
			return msg;
		}
		public void setMsg(String msg) {
			this.msg = msg;
		}
		public String getReciever() {
			return reciever;
		}
		public void setReciever(String reciever) {
			this.reciever = reciever;
		}
		
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值