关闭

JAVA网络编程

标签: java通信网络编程
484人阅读 评论(0) 收藏 举报
分类:

一、套接字(socket):

        套接字是网络中的一个抽象概念,它由网络地址和端口号组成。其中网络地址可以确定到网络中的某个计算机,而端口号则可以确定该计算机中的某个进程。

        在java中,使用套接字实现网络通信。网络通信的过程始终是客户端主动连接服务端,服务端可以根据需要返回一些信息。

        ServerSocket类,这个是服务端类,运行在服务端。

        Socket类,这个是客户端类,运行在客户端。

        从套接字读取信息时,在可以访问数据之前,读操作将会被阻塞。如果此时主机不可达,那么应用将要等待很长时间,并且因为受底层操作系统的限制而最终会导致超时。对于不同的应用,应该设置合理的超时值。

        Socket s = new Socket(host,port); //指定服务器的ip地址和端口号,当它被实例的同时就会尝试连接网络。

        s.setSoTimeout(10000);//设置超时值为10s

       如果已经设置了超时值,并且之后的读操作在没有完成之前就超过了时间限制,那么这个操作就会抛出SocketTimeoutException异常。这个是读取数据超时。

       还有一个是连接超时可以设置。

       Socket s = new Socket();//新建一个空的连接

       s.connect(new InetSocketAddress(host,port),timeout);//设置连接及连接超时时间

 二、客户端Client:

public class Client {
	private Socket socket;
	public Client(){
		try{
		   socket = new Socket("127.0.0.1",8088);			
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public void start(){		
		try {
			OutputStream out = socket.getOutputStream();
			PrintWriter writer = new PrintWriter(out);
			BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
			writer.println("你好啊,服务器!");
			writer.flush();			
			String str = reader.readLine();
			System.out.println("服务器:"+str);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args){
		new Client().start();
	}
}

三、实现服务器:

public class Server{
	private ServerSocket server;	
	public Server(){
		//网络连接一定要捕获异常
		try{
			server = new ServerSocket(8088);//建立一个负责监控端口8088的服务器程序
		} catch(Exception e){
			e.printStackTrace();
		}
	}
	public void start(){
		try{
		while(true){
		System.out.println("等待客户端连接。。。");
		Socket socket = server.accept();//告诉程序一直等待,直到有一个客户端连接进来,在连接进来之前一直阻塞。
		System.out.println("一个客户端连接了!");		
		/**
		 * 当一个客户端连接上后,启动一个线程,并将这个Socket交给这个线程,让线程和这个客户端交互。		
		 */
		ClientHandler handler = new ClientHandler(socket);
		Thread t = new Thread(handler);
		t.start();
		}
		}catch(Exception e){			
		}
	}
	public static void main(String[] args){
		Server server = new Server();
		server.start();
	}	
	/**
	 * 创建一个线程,用于接收客户端发过来的信息,并与客户端通信
	 */
	public class ClientHandler implements Runnable{
		private Socket client;//当前线程处理的客户端Socket
		public ClientHandler(Socket client){
			this.client = client;
		}
		public void run(){
			try {
				InputStream in = client.getInputStream();
				BufferedReader reader = new BufferedReader(new InputStreamReader(in));
				String str = null;
				while(true){
					str = reader.readLine();
					System.out.println("客户端说:"+str);
				}
			} catch (IOException e) {				
			}
		}
	}
}

四、半关闭:

      半关闭(half-close)提供了这样一种功能,套接字的一端可以终止其输出,同时仍旧可以接受来自另一端的数据,可以通过关闭一个套接字的输出流表示发送数据的请求已经结束,但是必须保持输入流处于打开状态。

      如下代码演示了如何在客户端使用半关闭方法: 

Socket socket = new Soket(host,port);
Scanner in = new Scanner(socket.getInputStream());
PrintWriter writer = PrinterWriter(socket.getOutputStream());
writer.print(....);
writer.flush();
socket.shutdownOutput();//now socket is half closed
while(in.hasNextLine() != null){String line = in.nextLine();...}
socket.close();

     这种协议只适应于一站式(one-shot)的服务,例如HTTP服务,在这种服务中,客户端连接服务器,发送一个请求,捕获响应信息,然后断开连接。

     相关方法:void shutdownOutput() ;将输出流设置为“流结束”

                       void shutdownInput();    将输入流设置为“流结束”

                       boolean  isOutputShutdown();   如果输出已被关闭则返回true

                       boolean  isInputShutDown();     如果输入已被关闭则返回true

五、可中断套接字:

     当使用Socket连接和读写过程中,在完成或者超时之前线程会一直处于阻塞状态,使用线程的interrupt并不能接触阻塞,这时你会发现程序的交互性会很差。为了中断套接字操作,可以使用java.nio包中提供的一个SocketChannel类来实现。

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:24467次
    • 积分:658
    • 等级:
    • 排名:千里之外
    • 原创:42篇
    • 转载:2篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论