浅谈java socket通信,并附源码

最近做的一个项目中,涉及到socket通信部分很多。在查阅大量资料后发现资料对于我自己大多分两种,过于理论或者代码深度太深看不懂。总觉得缺少中间桥梁让我平缓的过度。在观看郭霖大哥(我要给你生猴子)的视频讲解后恍然大悟,将讲解实例代码敲了下来并适当做了注解。

关于socket的基础知识网上很多很详细,我就不做过多的讲解,直接上代码。

客户端:

package socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class Clientsocket {
	public static void main(String[]args){
		Clientsocket client=new Clientsocket();
		client.start();
		
	}
	public void start(){
		BufferedReader reader=null;
		BufferedReader read=null;
		BufferedWriter writer=null;
		Socket socket=null;
		try {
			reader=new BufferedReader(new InputStreamReader(System.in));
			String outputstring;
			socket=new Socket("127.0.0.1", 9898);
			read=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			startServerListener(read);
			while(!(outputstring=reader.readLine()).equals("bye")){
				
				writer.write(outputstring+"\n");
				writer.flush();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				read.close();
				writer.close();
				socket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	/*
	 * 监听功能,新开一个线程不影响主线程的运行,是客户端能实时监听来自服务器的数据
	 */
	public void startServerListener(final BufferedReader reader){
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					String response;
					while((response=reader.readLine())!=null){
						System.out.println(response);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				
			}
		}).start();
	}

}
服务器:

package SeeHtml;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;


public class Server {
	BufferedWriter writer=null;
	BufferedReader reader=null;
	public static void main(String[]args){
		Server serversocket=new Server();
		serversocket.start();
	}
	public void start(){
		
		
		ServerSocket server=null;
		Socket socket=null;
		try {
			server=new ServerSocket(9898);
			while(true){
				socket=server.accept();
				/*
				 * 当没有客户端连接服务器时,accept方法会阻塞住
				 */
				System.out.println("client "+socket.hashCode()+"connect...");
				manageConnection(socket);
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				socket.close();
				server.close();
				
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		
	}
	/*
	 * 连接管理
	 * 每次客户端连接服务器是时都会生成一个socket,将socket传入manage进行处理和发送
	 */
	public void manageConnection(final Socket socket){
		new Thread(new Runnable(){
			public void run(){
				String string=null;
				try {
					reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
					writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
					
					/*
					 * 下面为测试代码,为了测试客户端的监听功能(客户端接受服务器主动发送数据)是否成功,定时发送心跳包
					 * 由于在匿名类中使用,writer需要设置为static或者全局变量
					 * new Timer().schedule(new TimerTask(){
						public void run(){
							try {
								writer.write("heart once...\n");
								writer.flush();
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							
						}
					},3000, 3000);
					*/
					
					/*
					 * 注意:主线程中需要加入while形成循环,否子运行一次就会推出接受客户端信息
					 * 同理,客户端在写消息的时候也需要注意这一点
					 */
					while(!(string=reader.readLine()).equals("bye")){
						System.out.println("client "+socket.hashCode()+":"+string);
						writer.write(string+"\n");
						writer.flush();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally{
					try {
						writer.close();
						reader.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
			}
		}).start();
	}

}
服务器跟客户端的代码中使用了很多循环和阻塞,为的是防止出现一端已经断开连接,另一端缺继续写入数据这种情况引发错误。

正如我上面所说,我们的代码使用了很多阻塞循环和线程,使得在真正使用时会出现运行效率低,使用不方便等问题。但是java官方也考虑到此问题,在jdk1.4之后推出了java.nio。随后有人对此又进行了封装,得到了不少好用的框架,比如mina,可以学一学。

在此附上郭霖大哥的课程教学连接:

点击打开链接http://www.imooc.com/learn/223



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值