今日更新
技术新闻
精彩专题
IBM软件技术专区
微软开发专区
技术文档中心
编程语言
网络通信
网络安全
LINUX/UNIX
软件工程与管理
数据库开发
WEB开发
企业应用与开发
移动开发
资源中心
原创专栏
开放系统世界
人才与培训
技术天地论坛
厂商列表
社区推荐

· 女性身体内部人体受孕..
· 十部顶级的变态与情色..
· 感情放纵让我毁了两个..
· 当我撞见姐姐和男友在..
· 卖淫少女惨遭泄愤民工..
· 偷拍街上的走光mm绝对..
· 百度打击google的广告
· 港娱乐圈与黑社会揭秘
赛迪网>>技术应用>>重点推荐
关键字: java;网络编程;socket
来  源: 赛迪网
比尔学Java:Java Socket篇
作者:Mac 发文时间:2002.09.28
比尔最近接到一个项目,是要在原来的系统上实现客户端与服务器的连接。原来的系统是用Java开发的,项目组讨后,决定应用Java提供的Socket类来解决问题。比尔是C开发的高手,对Java却只略知皮毛。所以,比尔一头扎进Java中,开始他的学习历程。当然,首先还要解决眼前的问题,学习Socket编程。

在学习Socket编程之前,先看看自己是否熟悉TCP、UDP、Ports等网络基本概念,要是还不熟悉的话就得先去补补课罗!

Socket 的基本概念


1、Socket,也就是俗称的套接字。

2、Sun Java中的定义:是运行在网络上的两个程序间双向通讯连接的末端,它提供客户端和服务器端的连接通道。Socket绑定于特定端口这样TCP层就知道将数据提供给哪个应用程序。

3、字面上的理解,Socket的意思是"插座、孔",你还可以把它形象地理解为打电话用的电话机,你从听筒里听到对方声音,同时将声音通过话筒传给对方。

我想你现在和我刚开始的时候一样:好像有点明白,又好像不是很明白,没关系,我希望通过下面例子的讲解你能够彻底地掌握它。在实例之前,让我们先来看看Socket实现的基本原理。

Socket编程实现原理


从连接的建立到连接的结束,每个Socket应用都大致包含以下几个基本步骤:

1、服务器端socket绑定于特定端口,服务器侦听socket等待连接请求;

2、客户端向服务器和特定端口提交连接请求;

3、服务器接受连接,产生一新的socket,绑定到另一端口,由此socket来处理和客户端的交互,服务器继续侦听原socket来接受其他客户端的连接请求;

4、连接成功后客户端也产生一socket,并通过它来与服务器端通讯(注意:客户端socket并不与特定端口绑定);

5、接下来,服务器端和客户端就通过读取和写入各自的socket来进行通讯。

注意:本文中只讲解基于TCP的Socket应用

Java中的Socket类


Java中提供两个类(在java.net包中)——Socket和ServerSocket来分别实现客户端和服务器端Socket。但Socket的实际工作是由抽象类SocketImpl的实例来完成的,这其实是设计模式中Abstract Factory模式的一个应用。

ServerSocket类的常用构造器和主要方法:

ServerSocket(int port)			在指定的端口号上产生一服务器端socket
Socket accept()				侦听socket,接受连接


Socket类的常见构造器和主要方法:

Socket(String host, int port)	生成一socket并连接至指定的主机和端口 
InputStream  getInputStream()	返回socket的输入流
OutputStream getOuputStream() 	返回socket的输出流


一个客户服务器实例


了解了上面的一些基本知识以后,我想大家现在都迫不及待地想亲自动手编写自己的socket,那就让我们开始吧!在这个例子中,我们模仿了一个Echo服务,它侦听3333端口。客户端接受用户键盘输入并向服务器端发出连接请求,服务器端接受客户端连接,连接成功后建立会话,客户端于是向服务器端发送用户输入信息,服务器端接收此信息并且简单返回给客户端。源码如下:

(服务器端)

/**
 * <p>Title:EchoServer.java </p>
 * <p>Description: EchoServer create a echo-like server at port 3333</p>
 * @author Mac
 * @version 2002/9/2
 */

import java.net.*;
import java.io.*;

public class EchoServer
{
    public static void main (String[] args) throws IOException
    {
        ServerSocket echoServer = null;
        try
        {
            echoServer = new ServerSocket(3333); //creat a server socket at port 
3333(问题一)
        }
        catch(IOException e)
        {
            System.err.println("Couldn't listen on port:3333");
            System.exit(-1);
        }

        Socket echoClient = null;
        try
        {
            echoClient = echoServer.accept(); //accept a connection
        }
        catch(IOException e)
        {
            System.err.println("IO error:" + e.getMessage());
            System.exit(-1);
        }
		
        PrintWriter out = new PrintWriter(echoClient.getOutputStream(),true);
        	//gets the socket's output stream and opens a PrintWriter on it
        //if you remove the argument true,what will happen?(问题三)
        BufferedReader in = new BufferedReader(
                            new InputStreamReader(echoClient.getInputStream()));
     		//gets the socket's input stream and opens a BufferedReader on it
        String strFromClient;

        while((strFromClient = in.readLine()) != null)
        {
            out.println("result is :" + strFromClient);
        }

        in.close();
        out.close();
        echoClient.close();
        echoServer.close();
    }
}

(客户端)
/**
 *<p>Title:EchoClient.java </p>
 *<p>Description: EchoClient creates a socket thereby getting a connection to 
echo-like server</p>
 * @author Mac Wang
 * @version 2002/8/30
 */

import java.net.*;
import java.io.*;

public class EchoClient
{

    public static void main(String[] args)
    {
        try
        {
Socket echoClient = new Socket("yourhostname",3333); 
//creat a new socket connected to host and port 3333
            PrintWriter out = new PrintWriter(echoClient.getOutputStream(),true);

            BufferedReader in = new BufferedReader(
                                new InputStreamReader(echoClient.getInputStream()));
            String fromServer,fromUser;
            BufferedReader stdIn = new BufferedReader(
                                   new InputStreamReader(System.in));
            	//gets the system input stream and opens a BufferedReader on it
            while ((fromUser = stdIn.readLine()) != null)
            {
                if (fromUser.equals("bye")) break; 
//when user types "bye" then end

                System.out.println("input is:" + fromUser);
                out.println(fromUser);

                fromServer = in.readLine();
                System.out.println(fromServer);
            }
            out.close();
            in.close();
            echoClient.close();
        }
        catch(UnknownHostException e)
        {
            System.err.println("Unknown host:yourhostname");
            System.exit(1);
        }
        catch(IOException e)
        {
            System.err.println("I/0 error:" + e.getMessage());
            System.exit(1);
        }
    }
}


现在大家可以分别运行Server和Client,看看程序运行效果(注意:你必须将yourhostname替换成你自己的主机名或IP地址)。并且思考以下几个问题:

1、把端口号换成2222后看看程序运行效果?那么89呢?是不是任何数字都可以呢?

2、如果不采用我们自己编写的echo server,而是连接到系统本身提供的echo server(端口号为7),试试看会发生什么情况,客户端Socket是否需要改变呢?

3、去掉PrintWriter中的参数True,看看程序运行的效果?

4、注意程序中是如何读取和写入Socket的?

5、试着多打开几个客户端,看看效果如何?

从问题5中大家可以看出来,上面的例子只支持一个用户连接,那么如何支持多用户的同时访问呢?最简单有效的方法就是利用多线程实现,每个线程对应一个用户连接,server接受一个client连接后,就新产生一个线程,并交由它去处理余下的工作。下面就是支持多用户的服务器端实现:

/**
 *<p>Title:EchoMultiServer </p>
 *<p>Description: EchoServer create a echo-like server at port 3333 which supports 
multi-client</p>
 * @author Mac Wang
 * @version 2002/9/2
 */
import java.net.*;
import java.io.*;
class EchoMultiServerThread extends Thread
{
    private Socket echoClient = null;
    public EchoMultiServerThread(Socket socket)
    {
	super("EchoMultiServerThread");
	this.echoClient = socket;
    }
    public void run()
    {
		try
        {
	    	PrintWriter out = new PrintWriter(echoClient.getOutputStream(), 
true);
	    	BufferedReader in = new BufferedReader(
					    new 
InputStreamReader(echoClient.getInputStream()));
	    String strFromClient;
		    while ((strFromClient = in.readLine()) != null)
            {
	        	out.println("result is :" + strFromClient);
	    	}
	    out.close();
		    in.close();
	    	echoClient.close();
		}
        catch (IOException e)
        {
			System.err.println("IO Error:" + e.getMessage());
            System.exit(-1);
		}
    }
}
public class EchoMultiServer
{
    public static void main (String[] args) throws IOException
    {
        ServerSocket echoServer = null;
        boolean listening = true;

        try
        {
            echoServer = new ServerSocket(3333);
        }
        catch(IOException e)
        {
            System.err.println("Couldn't listen on port:3333.");
            System.exit(-1);
        }
        while (listening)
            new EchoMultiServerThread(echoServer.accept()).start();

        echoServer.close();
    }
}


大家运行这段程序,看看和开始的Server有什么区别,程序有什么地方可以改进的呢?好啦,大家现在感觉怎么样?是不是觉得Socket编程也不过如此,可千万不要太骄傲轻敌哦,不信你就自己动手编个复杂的程序,保准有很多问题在等着你!

现在,比尔对Java编程产生了兴趣,决定继续学下去,并为自己定了个计划。接下来,他打算学学Datagram。

(责任编辑 Sunny




赛迪网推出“IT博客”,花不到一分钟就完成注册
评论】 【推荐】 【 】 【打印】 【关闭

·Linux专区· ·黑客攻防·
· Linux下添加硬盘、分区、格式化任务详解
· FreeBSD服务器的安装与优化之优化篇
· 初学者入门:FreeBSD服务器的安装与优化
· 金企鹅杯两岸四地开源软件大赛圆满结束
· 如何提高Linux系统安全性的十大招数
· 构筑Linux防火墙之为个人用户设置防火墙
· 谁更安全?黑客眼中的防火墙与路由器
· 识破骗局 练就识别QQ活动真伪火眼金睛
· 应用安全大有可为:目的、挑战、总结
· 道高一尺魔高一丈:安全防御的动感魅力
· 警惕网络“内”院起火 积极谋求安内之路
· HHCTRL漏洞被黑客利用 疯狂传播木马
·中国信息化· ·成功案例·
· ERP普及化是饮鸩止渴 精细化才是应用之道
· 赛门铁克第八期《互联网安全威胁报告》解析
· 抢食“数字工商” 国产中间件杀出血路
· 从IBM等操作系统的发展看软件创新的启示
· 服务成就蓝色快车 品牌是怎样炼成的?
· 三大技术应用大会合为一体甲骨文上演三重奏
· 南阳教育城域网 拆掉学校间的“围墙”
· 金算盘助申意美步入信息化快车道
· 不为人知的索尼信息化 谁是幕后英雄?
· InforBus/Q在穗高速路联网收费系统中的应用
· J2EE构建最新金融理念和运作模式的网上银行
· 食品安全令人担心 信息化能否保驾护航
*姓  名: 更多资料 了解方案 认识厂商
*单位名称:
*联系电话:
*电子邮件:
    
◆ 相关文章   ◆ 站内热点推荐
· J2EE 1.4又添新功能
· 一种纯Java的数据库—JDataStore
· 利用Preferences API管理缺省参数
· [Java]:基于JXTA的P2P应用开发
· 说文解字:解读Java中的“垃圾方言”
· 网管员论坛
· 开发者之家
· WLAN无限未来
· 我是如何掉进C#的……
· 中国“人件”非正式调查

   
合作网站: IBM dW中国网站 LinuxAID 软件工程专家网 中国系统分析员 UMLChina MATRIX Mobile2008 JavaResearch 华储网 UML软件工程组织 中国JAVA手机网 JAVA中文站 金山在线 海量科技