`

(二) 实现服务器

 
阅读更多

一个简单的服务器,可以向客户端发送信息。一旦启动了服务器程序,它便等待某个客户端连接到它的端口。这里选用8189,因为所有标准服务都不使用这个端口。
(1)ServerSocket类实现服务器套接字。
例:建立一个负责监控端口8189的服务器

    ServerSocket serverSocket = new ServerSocket(8189);

 (2)侦听并接受到此套接字的连接。

    Socket incoming = serverSocket.accept();

 (3)当通过网络向该端口发送了正确的连接请求,该方法就会返回一个表示连接已经建立的Socket对象。可以使用儿歌对象来得到输入流和输出流

    InputStream inStream = incoming.getInputStream();
    OutputStream outStream = incoming.getOutputStream();

 

服务器发送给服务器输出流的所有信息都会成为客户端程序的输入,同时来自客户端程序的所有输出都会被包含在服务器输入流中。
(4)最终,关闭连接进来的套接字。

    incoming.close();

 

DEMO

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
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 EchoServer {
	public static void main(String[] args) {
		try{
			ServerSocket serverSocket = new ServerSocket(8189);
			Socket incoming = serverSocket.accept();
			
			try{
				
			
				InputStream inStream = incoming.getInputStream();
				OutputStream outStream = incoming.getOutputStream();
				
				BufferedReader in = new BufferedReader(new InputStreamReader(inStream, "gbk"));
				//也可以使用Scanner
//				Scanner in = new Scanner(is);
				//使用OutputStreamWriter 虽然通过 \n 可以换行,
				//但是第二行字符的起始位置与第一行字符的终止位置相同
				OutputStreamWriter outWrite = new OutputStreamWriter(outStream, "gbk");
				//使用PrintWriter的情况下第二行自动提到最前面
				PrintWriter out = new PrintWriter(outWrite, true);
				
				out.print("Hello! Enter BYE to exit.");
				
				boolean done = false;
				
				String line = null;
				while((line=in.readLine())!=null){
					System.out.println(line);
					out.println("Echo: " + line);
					out.println("Hello! Enter BYE to exit.");
					if("bye".equalsIgnoreCase(line.trim())){
						out.write("bye");
						break;
					}
				}
				
				//Scanner用法
//				while(!done && in.hasNextLine()){
//				String line = in.nextLine();
//				System.out.println(line);
//				out.println("Echo: " + line);
//				out.println("Hello! Enter BYE to exit.");
//				if("bye".equalsIgnoreCase(line.trim())){
//					done = true;
//				}
//			}
				
			}finally{
				incoming.close();
			}
			
			System.out.println(serverSocket.isClosed());
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

 

 

1.为多个客户端服务
通常希望有多个客户端同时连接到服务器上,通常,服务器总是不间断地运行在服务器计算机上,来自整个因特网的用户系统同时使用服务器。拒绝多客户端连接将使得某个用户可能回因长时间地连接服务而独占服务。其实可以通过线程来处理该问题。
每当程序建立一个新的套接字连接,也就是说当成功调用accept的时候,将创建一个新的线程来处理服务器和客户端之间的连接,而主程序将立即返回并等待下一个连接。
(1)为了实现这个机制,服务器应该具有类似以下代码的循环操作:

    while(true){
        Socket incoming = serverSocket.accept();
        Runnable run = new ThreadedEchoHandler(incoming);
        Thread t = new Thread(r);
        t.start;
    }

 

(2)ThreadedEchoHandler类实现了Runnable接口,而且它的run方法中包含了与客户端循环通信的代码。

 

DEMO

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ThreadedEchoServer {
	public static void main(String[] args) {
		try{
			int i = 1;
			ServerSocket server = new ServerSocket(8189);
			while(true){
				Socket incoming = server.accept();
				System.out.println("Spawning : " + i);
				Runnable runnable = new ThreadedEchoHandler(incoming);
				Thread t = new Thread(runnable);
				t.start();
				i++;
			}
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class ThreadedEchoHandler implements Runnable {

	private Socket incoming;
	
	public ThreadedEchoHandler(Socket incoming){
		this.incoming = incoming;
	}
	
	@Override
	public void run() {
		try{
			try{
				InputStream inStream = incoming.getInputStream();
				OutputStream outStream = incoming.getOutputStream();
				
				BufferedReader in = new BufferedReader(new InputStreamReader(inStream, "gbk"));
				PrintWriter out = new PrintWriter(new OutputStreamWriter(outStream, "gbk"), true);
				
				String line = null;
				while((line=in.readLine())!=null){
					System.out.println("in:" + line);
					out.println("Echo : " + line);
					if(line.trim().equals("bye")){
						break;
					}
				}
			}finally{
				incoming.close();
			}
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

 

2.半关闭
半关闭(half-close)提供了这样一种能力:套接字连接的一段可以终止其输出,同时仍旧可以接受来自另一端的数据。
这是一种很典型的情况,例如我们在向服务器传输数据,但是并不知道要传输多少数据。在写一个文件时,我们只需要在数据写入后关闭文件即可。但是,如果关闭一个套接字,那么与服务器的连接将立刻断开,因而也就无法读取响应。
使用半关闭的方法就可以解决上述问题。可以通过关闭一个套接字的输出流来表示发送给服务器的请求数据已经结束,但是必须保持输入流处理打开状态。
例:在客户端使用半关闭

        Socket socket = new Socket(host, port);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(outStream, "gbk"), true);
       
        out.println(...);
        //禁用此套接字的输出流
        socket.shutdownOutput();
        String line = null;
        while((line=in.readLine())!=null){
            ...
        }
        //此套接字的输入流置于“流的末尾”。
        socket.shutdownInput();
        socket.close();

 


服务器端将读取输入信息,知道到达输入流的结尾,然后再发送响应。
该协议只适用于一站式(ont-shop)的服务,例如HTTP服务,在这种服务中,客户端连接服务器,发送一个请求,捕获相应信息,然后断开连接。

分享到:
评论

相关推荐

    DWR3实现服务器端向客户端精确推送消息

    在“DWR3实现服务器端向客户端精确推送消息”这一主题中,我们将深入探讨如何利用DWR3进行服务器到客户端的消息推送,以及这种技术的优势和应用。 首先,理解DWR3的工作原理是至关重要的。DWR3通过建立一个安全的...

    java实现FTP服务器

    ### Java实现FTP服务器的关键知识点 在探讨如何使用Java实现FTP(File Transfer Protocol)服务器之前,我们首先需要理解FTP的基本概念及其工作原理。FTP是一种用于在网络上进行文件传输的标准协议,它支持上传...

    50行Python代码实现代理服务器

    这里的代理服务器,是指二级代理服务器。比如:A可以访问B,B可以访问C,A不能直接访问C。这时,如果在B开一个二级代理,就可实现A访问C。现有的工具有CCProxy。 这里就是使用Python简单的实现一个二级代理。

    c++实现Ftp服务器

    知识点二:FTP服务器 FTP(File Transfer Protocol)是用于在网络上传输文件的协议。FTP服务器是指提供文件传输服务的服务器。FTP服务器可以实现文件上传、下载、删除、创建目录等操作。 知识点三:C++实现FTP...

    VC下实现服务器和客户端socket通信

    在本文中,我们将深入探讨如何在Visual C++(VC)环境下实现服务器和客户端之间的Socket通信。Socket编程是一种网络编程技术,用于在两台计算机之间建立通信链路,使得数据能够双向传输。对于初学者来说,这是一个很...

    FTP服务器与客户端设计与实现

    在这个主题中,我们将深入探讨FTP服务器与客户端的设计与实现,包括文件操作、用户权限管理等关键概念。 一、FTP服务器基础 FTP服务器是提供文件传输服务的软件,它接收客户端的连接请求,处理文件的上传、下载以及...

    python实现TCP服务器

    1、程序通过实现一个服务器类,可以在一台电脑上实例化多个服务器(端口号需要设置不相同),每个客户端允许带多个客户端,可自行修改上限数量 2、实现异常捕获防止程序报错卡死 3、实现客户端处理类,服务器能通过...

    实现多服务器负载均衡

    ### 实现多服务器负载均衡的关键知识点 #### 一、负载均衡技术概述 负载均衡是一种用于在多台计算机、网络链接、CPU、硬盘或其他资源中分配工作负载的技术,目的是优化资源使用、最大化吞吐量、最小化响应时间并...

    多线程Web服务器的设计与实现

    本实验的主题是“多线程Web服务器的设计与实现”,这涉及到并发处理和网络通信的核心概念。下面将详细讨论相关知识点。 1. **多线程**:多线程是指在一个程序中可以同时执行多个独立的线程。在Web服务器中,多线程...

    实现FTP服务器文件传输课程设计

    在本课程设计中,我们将深入探讨如何实现一个FTP(File Transfer Protocol)服务器,这是一种用于在网络上进行文件传输的标准协议。FTP允许用户从远程主机上传、下载文件,为分布式系统中的数据共享提供了便利。以下...

    利用socket实现客户端服务器之间简单通信

    本教程将深入探讨如何利用Socket库在Python中实现客户端与服务器之间的简单通信,这涉及到TCP/IP协议中的三次握手和四次挥手过程。 首先,我们来看TCP(传输控制协议)的三次握手。三次握手是为了确保连接的可靠性...

    c#实现FTP服务器

    c#实现FTP服务器, 功能 ①、按标准FTP协议登录FTP服务器,进行身份验证; ②、显示远程目录、文件列表,进行目录切换; ③、目录、文件列表的排序显示(文件名、时间、类型); ④、能上传文件、下载、删除文件...

    socket实现HTTP代理服务器

    ### Socket 实现 HTTP 代理服务器的关键知识点 #### 一、HTTP 代理服务器的基本概念与工作原理 HTTP 代理服务器是一种中介服务,它位于客户端(如浏览器)与目标服务器之间,帮助客户端发送请求到目标服务器,并将...

    Linux 服务器集群系统实现方案详解

    Linux 服务器集群系统实现方案详解 Linux 服务器集群系统实现方案详解是一种提高服务器安全性和可靠性的方法。集群技术可以将多台服务器组成一个单一的系统,并以单一系统的模式进行管理。这样可以提供高可靠性的...

    C#实现的通过webservice 获取服务器端 程序实现 系统自动升级

    对于C#开发者来说,利用WebService技术来实现服务器端程序的自动升级是一个高效且可靠的方法。本篇将详细探讨如何利用C#来实现这一功能。 首先,理解WebService:WebService是一种基于标准的,能够跨越不同操作系统...

    基于SocketAsyncEventArgs(IOCP)的高性能TCP服务器实现(二)——服务端信息接收窗体实现(C#)

    首先,我们从标题"基于SocketAsyncEventArgs(IOCP)的高性能TCP服务器实现(二)"了解到,这是一个系列的第二部分,主要关注服务端的信息接收。IOCP(I/O完成端口)是Windows操作系统提供的一种高效的I/O模型,尤其...

    JAVA实现XMPP客户端和服务器

    开发者可以通过Smack库与Openfire进行交互,实现服务器功能。 四、XMPP客户端实现 1. Smack API:使用Smack API,开发者可以创建XMPP客户端,实现登录、注销、发送接收消息、管理联系人等功能。 2. Android集成:...

    android studio连接云服务器mysql实现登录注册

    总之,实现"android studio连接云服务器mysql实现登录注册"涉及到Android应用开发、网络编程、数据库操作和服务器端API设计等多个方面。理解并掌握这些知识点,将有助于你构建出稳定、安全的移动应用。在实际开发...

Global site tag (gtag.js) - Google Analytics