Socket通信

来源:互联网 发布:先锋软件股份有限公司 编辑:程序博客网 时间:2024/05/16 07:02

Socket通信

第一节 socket通信的服务端和客户端的代码大致结构

一、服务端代码结构(红色字体处为关键代码)

 

    try {

           ServerSocketserver = new ServerSocket(4567); 

//创建一个ServerSocket,设定监听端口号

          

           Socketsocket = server.accept();

//accept()方法会阻塞,直到客户请求的到来;

//有客户请求到来则产生一个Socket对象,此时连接建立起来,并继续执行

 

           InputStream is = socket.getInputStream();

//Socket对象中获取输入流

 

                //接下来可以将输入流再次包装,如:

//sin =new BufferedReader(new InputStreamReader(is));

 

           OutputStream os = socket.getOutputStream();

//Socket对象中获取输出流

 

//接下来可以将输出流再次包装,如:

//sout =new DataOutputStream(os);

 

           while(flag)

{

    利用输入流或输入流的包装流、输出流或输出流的包装流 接收发出信息

 

    //在某些必要的时候设法跳出死循环

}

 

//以下是结束通信需要使用的代码

           os.close();

           is.close();

           socket.close();

           server.close();//如果服务端需要继续等待新的客户端来连接,则不使用此句

           System.exit(0);//如果服务端需要停止运行,才使用此

       }

catch (IOException e) {System.out.println(e);}

 

二、客户端代码结构(红色字体处为关键代码)

 

    try {

           Socketsocket = new Socket("localhost", 4567);

//向服务端发出请求,参数设定了服务端的主机号和监听端口

//如果连接服务端不成功,该构造方法new Socket(…)会抛出IOException

//如果连接服务端成功,则产生一个Socket对象,此时连接建立起来,并继续执行

 

           InputStream is = socket.getInputStream();

//Socket对象中获取输入流

 

//这里可以将输入流再次包装,如:

//sin =new BufferedReader(new InputStreamReader(is));

 

           OutputStream os = socket.getOutputStream();

//Socket对象中获取输出流

 

//这里可以将输出流再次包装,如:

//sout =new DataOutputStream(os);

 

while(flag)

{

    利用输入流或输入流的包装流、输出流或输出流的包装流 接收发出信息

 

    //在某些必要的时候设法跳出死循环

}

 

//以下是结束通信需要使用的代码

           os.close();

           is.close();

           socket.close();

           System.exit(0); //如果客户端需要停止运行,才使用此

       }

catch (IOException e) {System.out.println(e);}

 

总结:我猜想

1.服务端维持一个ServerSocket对象,一个Socket对象;客户端维持一个Socket对象;

服务端维持的这个Socket对象与客户端维持的这个Socket对象互为一一对应。

2.当客户端Socket对象关闭,相应的服务端Socket对象也应当紧接着关闭;

3.如果服务端需要有与多个客户端通信的能力,那么应当始终监听,即有一个线程始终执行下述语句:

Socket socket = server.accept();

欲实现此目的,代码应含有下述代码结构:

While(true)

{

    ...

    Socket socket = server.accept();

    ...

}

 

 

 

第二节示例

 

本示例参见参见《Java程序设计》宋中山严山钧的P297。

本示例欲使服务端的接收和发送同时进行,因此又开启了一个线程

本示例欲使客户端的接收和发送同时进行,因此又开启了一个线程

 

一、服务端代码:

import java.io.*;

import java.net.ServerSocket;

import java.net.Socket;

 

publicclass Serverimplements Runnable {

    ServerSocket server = null;

    Socket socket = null;

    Boolean flag = true;

    Thread c;

    BufferedReader sin;

    DataOutputStream sout;

 

    publicstaticvoid main(String[] args) {

       new Server().serverStart();

    }

 

    publicvoid serverStart() {

       try {

           server =new ServerSocket(4567); 

           System.out.println("端口号:" + server.getLocalPort());

          

           socket =server.accept();

           InputStream is = socket.getInputStream();

           sin =new BufferedReader(new InputStreamReader(is));

           OutputStream os = socket.getOutputStream();

           sout =new DataOutputStream(os);

           c =new Thread(this);

           c.start();

           String aline;

 

           while (flag) //该块用于接收

{

              while ((aline =sin.readLine()) !=null)

//如果客户端关闭,这里读出的将为null。该块用于发送

//该循环跳出后,应调用一次flag = false;

              {

                  System.out.println("客户端对服务器说" + aline);

                  if (aline.equals("bye")) {

                     flag =false;

                     break;

                  }

              }

              flag =false;

           }

           sout.close();

           os.close();

           sin.close();

           is.close();

           socket.close();

           System.exit(0);

          

       } catch (IOException e) {

           System.out.println(e);

       }

    }

 

publicvoid run() {     //该块用于发送

       while (true) {

           try {

              int ch;

              while ((ch = System.in.read()) != -1) {

                  sout.write((byte) ch);

                  if (ch =='\n')

                     sout.flush();

              }

           } catch (IOException e) {

              System.out.println(e);

           }

       }

    }

 

    publicvoid finalize() {

       try {

           server.close();

       } catch (IOException e) {

           System.out.println(e);

       }

    }

}

 

二、客户端代码

import java.io.*;

import java.net.Socket;

 

publicclass Clientimplements Runnable {

 

    Socket socket = null;

    Boolean flag = true;

    Thread c;

    BufferedReader sin;

    DataOutputStream sout;

 

    publicstaticvoid main(String[] args) {

       new Client().clientStart();

    }

 

    publicvoid clientStart() {

       try {

           socket =new Socket("localhost", 4567);

 

           System.out.println("已建立连接");

 

           InputStream is = socket.getInputStream();

           sin =new BufferedReader(new InputStreamReader(is));

           OutputStream os = socket.getOutputStream();

           sout =new DataOutputStream(os);

           c =new Thread(this);

           c.start();

           String aline;

          

           while (flag) //该块用于接收

           {  

               while ((aline =sin.readLine()) !=null)

//如果客户端关闭,这里读出的将为null

//该循环跳出后,应调用一次flag = false;

              {

                  System.out.println("服务端对客户端说" + aline);

                  if (aline.equals("bye")) {

                     flag =false;

                     break;

                  }

              }

              flag =false;

           }

           sout.close();

           os.close();

           sin.close();

           is.close();

           socket.close();

           System.exit(0);

      

 

       } catch (IOException e) {

           System.out.println(e);

       }

    }

 

    publicvoid run() {     //该块用于发送

       while (true) {

           try {

              int ch;

              while ((ch = System.in.read()) != -1)

              {

                  sout.write((byte) ch);

                  if (ch =='\n')

                     sout.flush();

              }

           } catch (IOException e) {

              System.out.println(e);

           }

       }

    }

}

 

 

原创粉丝点击