欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java之通信基础 博客分类: java通信 java通信Socket输入输出流

程序员文章站 2024-03-24 22:01:04
...

    最近学习java的通信处理,感觉并不容易,若文中出现差错,希望指正。

    在网络中,最基础的通信即服务器与一个客户机之间的通信。

    首先,创建服务器

    ServerSocket server = new ServerSocket(port);

    以上代码就实例化了一个服务器,其中参数port为端口号。每个机器都有0~65535端口,每个端口可供一个程序通信使用。通常情况下,我们建立的服务器应避免使用0~1024端口,它们默认是某些程序的端口。

    创建好服务器,接下来服务器要做的事就是等待,一直到有人连接上这个服务器。这个等待过程也称为阻塞过程,代码如下:

     Socket client = server.accept();

     连接上服务器时,这个连接对象对服务器而言就是客户机了。

    现在服务器与客户机连接上了,具备了两者之间相互通信的基本条件。现在利用输入输出流来传递两者之间要交流的信息。

    InputStream instream = client.getInputStream();
    OutputStream outstream = client.getOutputStream();

    这个输入输出流是从连接对象中得到的。实际上,从逻辑上来看,客户机的输出流即服务器的输入流,同样,客户机的输入流即服务器的输出流。如果允许的话,我们也可以从服务器中得到输入输出流,但是ServerSocket这个类并没有提供得到输入输出流的方法。

    现在想让客户连接上服务器时,客户机上显示“welcome”,可以利用以下代码实现:

    String s = "welcome!";
     byte[] data = s.getBytes();//字符串转换为字节流
     outstream.write(data);//用输出对象写出数据
     outstream.flush();//强制输出

    这段代码产生的效果就像是将服务器的信息发送给客户机。但是,看这段代码时我感觉很奇怪,因为服务器是发出信息,所以按理来讲,输出对象应该是服务器的,但是这个输出对象outstream却是从客户机那里得到的。其实我这是把效果想当然地对应到它的过程中了,而这恰恰是错误的。这段代码的过程是这样的,在有客户机连上服务器时,客户机的输出流对象就把“welcome”写在客户机界面上。

    接下来就是客户机发送消息给服务器。

    //客户端向服务器发消息
    int n = instream.read();
    while(n != '%'){
     //打印接收字符
    System.out.print((char)n);
   n = instream.read();
    }

    输入流对象读取方法read(),是一个字节一个字节读取,也就是在客户机没打一个字符,服务器就打印一个字符,所以要用到while循环,以上代码是当遇到“%”时停止接收,“%"在这里相当于结束字符。read()返回的是int型,只需在打印接收字符时将其转型为char即可。

    想要实现客户机输入一行字符串之后再把信息发送给服务器的话,只需对 n = instream.read();这行代码稍加修改即可,关键的地方就是利用字符缓冲区StringBuffer,在遇到换行符时,将字符缓冲区中的字符组输出就行了。

    最后,我们加入一个判断语句,输入某个字符或字符串,比如”END“,就将客户机关闭,执行代码:client.close();。

    但是这个程序执行完后,服务器也关闭了。要让服务器不关闭,一个简单的办法就是在创建一个服务器后,将后面的代码都套在while(true){}中。这并非一个好方法,但不影响我们对服务器和客户机之间通信的测试。

    不过,这里还有一个缺陷,就是服务器只能连接上一个客户机。我们可以用线程解决这个问题,写一个线程类只需将创建客户机之后的代码复制进去,并重写构造函数,使能传入参数Socket client。

    这样就实现了一个比较基础的服务器和客户机之间的通信。