首页 > 学院 > 开发设计 > 正文

javaSocket编程

2019-11-14 14:59:18
字体:
来源:转载
供稿:网友

一.网络通信,常见的结构是C/S模式。客户端在需要服务时向服务器请求连接,服务端被动接收连接,建立连接后,双方开始通信。服务器进程一般作为守护进程,一直运行,不断监听网络端口,被动接收客户端的请求,当接收到客户的请求时,会启动一个服务进程来处理客户的请求,并继续监听网络端口。

(上图转自:http://tutorials.jenkov.com/java-networking/index.html)

二.网络上进程之间通过双向的通信连接来实现信息的交换。这样连接的一端称为一个Socket。Socket由ip号和端口号确定。在java中使用Socket来实现基于TCP/IP协议的网络程序,主要涉及到下面几步:

客户端:

1.根据服务器的IP和端口号,建立Socket

2.打开输入、输出流

3.对Socket进行读写

4.关闭输入、输出流,关闭套接字

服务器端:

1.根据端口号建立ServerSocket

2.被动监听客户端请求

3.当监听到客户端请求时,接收请求,启动工作线程,处理请求。若不再接收请求时,进入4;否则,继续监听,转2

4.关闭ServerSocket

下面以例子来说明:

客户端代码:

package com.net.examples;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;public class Client {    /**     * @param args     * @throws IOException      * @throws UnknownHostException      * @throws InterruptedException      */    public static void main(String[] args) throws UnknownHostException,         IOException, InterruptedException {        //这里假设有三个client,每个client分别发送一次请求        int clientCount = 3;        MyRunable run = new MyRunable();        while(clientCount > 0){            //每个线程模拟一个client,三个线程名分别为1,2,3            new Thread(run,clientCount+"").start();            clientCount--;        }    }}//定义MyRunable,重写run方法实现client线程class MyRunable implements Runnable{    public void run() {        int messCount = 2;        Socket socket = null;        DataOutputStream o = null;        DataInputStream in = null;        try {            //1.创建Socket,建立连接            socket = new Socket("127.0.0.1",8080);            //2.打开输入输出流            o = new DataOutputStream(socket.getOutputStream());            in = new DataInputStream(socket.getInputStream());            System.out.PRintln("Clients begin send messages");                //每个client对Socket写两次            while(messCount > 0 ){                try {                    //3.对Socket进行写                    o.writeUTF("" + messCount);                    o.flush();                } catch (IOException e) {                    e.printStackTrace();                }                System.out.println("I am client:"+Thread.currentThread().getName() +",I send message:" + messCount);                messCount--;            }            //对Socket进行读            System.out.println("I am client:" + Thread.currentThread().getName() + ",and server "+ in.readUTF() + "(me!)");        } catch (IOException e2) {            e2.printStackTrace();        } finally{            try {                //4.关闭输入输出流,关闭socket,释放资源                o.close();                in.close();                socket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

服务端代码:

package com.net.examples;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;//Serverpublic class Server {    private static int clientCount = 3;    //Server线程结束运行条件,这里是假设知道一共会收到三次客户端请求    private static boolean isStop(){        return clientCount == 0 ? true:false;    }    public static void main(String[] args) throws IOException, InterruptedException {        //1.建立ServerSocket        ServerSocket serverSocket = new ServerSocket(8080);        //2.监听客户端请求        while(!isStop()){            //3.接收到客户端请求,并启动一个线程处理            Socket client = serverSocket.accept();            new MyThread(client,clientCount).start();            clientCount--;        }        //4.关闭ServerSocket        serverSocket.close();    }}//客户端请求处理线程class MyThread extends Thread{    private Socket clientSocket;    private int id;    private DataInputStream input;    private DataOutputStream output ;    public MyThread (){    }    public MyThread(Socket soc,int i){        this.clientSocket = soc;        this.id = i;    }    public void run(){        try {            //获得输入输出流            input = new DataInputStream((clientSocket.getInputStream()));            output = new DataOutputStream(clientSocket.getOutputStream());            int count = 2;            //读取Socket            while(count > 0){                System.out.println("I am server.I have received message:" + input.readUTF() + ",from" + id);                count --;            }            //写Socket            output.writeUTF("respose to client" + id);            output.flush();;        } catch (IOException e) {            e.printStackTrace();        }finally {            try {                //释放资源,关闭连接                input.close();                output.close();                clientSocket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

运行结果如下:

client:

Server:

 

不过,后来我稍微地改了下Client.java文件中MyRunable.java,输出流o,在对Socket写完之后,就调用了o.close()方法,而不是在读完Socket后释放掉,重新跑程序后client跑的就有错出现了,Server程序没出错。具体如改动下红色的部分,而报错也如下图:

我的理解是,输出流不用了,所以就close()了,为什么在读Socket时(58行的代码),会报socket closed这样的出错信息。难道调用o.close()时,会关闭socket??或者是其他原因,实在不理解,刚刚看着java Socket这一块,好多不清楚。麻烦看到的童鞋帮解答下。。。


上一篇:游戏中的音效

下一篇:Netty(一)引题

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表