网络编程

Socket网络编程

Socket套接字。在java.net.Socket包下。

1)网络通信模型:C/Sclient/server,客户端/服务器端;B/Sbrowser/server,浏览器端/服务器端;C/S结构的优点:应用的针对性强,画面绚丽,应用功能复杂。缺点:不易维护。B/S结构的优点:易于维护。缺点:效果差,交互性不强。

2Socket:封装着本地的地址,服务端口等信息。ServerSocket:服务端的套接字。

服务器:使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。

客户端:使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。

3)永远都是Socket去主动连接ServerSocket。一个ServerSocket可以接收若干个Socket的连接。网络通信的前提:一定要捕获异常。

4Socket连接基于TCP/IP协议,是一种长连接(长时间连着)。

5)读取服务器信息会阻塞,写操作不会。

6)建立连接并向服务器发送信息步骤:通过服务器的地址及端口与服务器连接,而创建Socket时需要以上两个数据。连接成功后可以通过Socket获取输入流和输出流,使用输入流接收服务端发送过来的信息。关闭连接。

7)连接服务器:一旦Socket被实例化,那么它就开始通过给定的地址和端口号去尝试与服务器进行连接(自动的)。这里的地址"localhost"是服务器的地址,8088端口是服务器对外的端口。我们自身的端口是系统分配的,我们无需知道。

8)和服务器通信(读写数据):使用Socket中的getInputStream()获取输入流,使用getOutputStream()获取输出流。

9)ServerSocket构造方法要求我们传入打开的端口号,ServerSocket对象在创建的时候就向操作系统申请打开这个端口。

10)通过调用ServerSocketaccept方法,使服务器端开始等待接收客户端的连接。该方法是一个阻塞方法,监听指定的端口是否有客户端连接。直到有客户端与其连接并接收客户端套接字,否则该方法不会结束。

eg1.1:客户端ClientDemo

private Socket socket;

public void send(){

try{ System.out.println("开始连接服务器"); socket=new Socket("localhost",8088);

InputStream in=socket.getInputStream();//获取输入流

       OutputStream out=socket.getOutputStream();//获取输出流

/**将输出流变成处理字符的缓冲字符输出流*/

PrintWriter writer=new PrintWriter(out); writer.println("你好!服务器!");

/**注意,写到输出流的缓冲区里了,并没有真的发给服务器。想真的发送就要作真实的写操作,清空缓冲区*/

writer.flush();

/**将输入流转换为缓冲字符输入流*/

BufferedReader reader=new BufferedReader(new InputStreamReader(in));

/**读取服务器发送过来的信息*/

String info=reader.readLine();//读取服务器信息会阻塞 System.out.println(info);

writer.println("再见!服务器!"); writer.flush();

info=reader.readLine(); System.out.println(info);

}catch(Exception e){ e.printStackTrace(); } }

public static void main(String[] args){

ClientDemo demo=new ClientDemo(); demo.send();//连接服务器并通信 }

eg1.2:服务器端ServerDemo类(不使用线程)

private ServerSocket socket=null; private int port=8088;

/**构建ServerDemo对象时就打开服务端口*/

public ServerDemo(){

try{ socket=new ServerSocket(port); }catch(Exception e){ e.printStackTrace(); } }

/**开始服务,等待收受客户端的请求并与其通信*/

public void start(){

try{ System.out.println("等待客户端连接……"); Socket s=socket.accept();

//获取与客户端通信的输入输出流

InputStream in=s.getInputStream(); OutputStream out=s.getOutputStream();

//包装为缓冲字符流

PrintWriter writer=new PrintWriter(out);

BufferedReader reader=new BufferedReader(new InputStreamReader(in));

//先听客户端发送的信息

String info=reader.readLine();//这里同样会阻塞 System.out.println(info);

//发送信息给客户端

writer.println("你好!客户端"); writer.flush();

info=reader.readLine(); System.out.println(info);

writer.println("再见!客户端"); writer.flush();

socket.close();//关闭与客户端的连接

}catch(Exception e){ e.printStackTrace(); } }

public static void main(String[] args){ System.out.println("服务器启动中……");

ServerDemo demo=new ServerDemo(); demo.start(); }

eg2:服务器端ServerDemo类(使用线程),start()方法的修改以及Handler

public void start(){

try{while(true){ System.out.println("等待客户端连接……"); Socket s=socket.accept();

/** 当一个客户端连接了,就启动一个线程去接待它 */

Thread clientThread=new Thread(new Handler(s)); clientThread.start();    }

}catch(Exception e){ e.printStackTrace(); }  }

/** 定义线程体,该线程的作用是与连接到服务器端的客户端进行交互操作 */

class Handler implements Runnable{

private Socket socket;//当前线程要进行通信的客户端Socket

public Handler(Socket socket){//通过构造方法将客户端的Socket传入

this.socket=socket; }

public void run(){

        try{ //获取与客户端通信的输入输出流

  InputStream in=socket.getInputStream();OutputStream out=socket.getOutputStream();

  PrintWriter writer=new PrintWriter(out);//包装为缓冲字符流

  BufferedReader reader=new BufferedReader(new InputStreamReader(in));

      String info=reader.readLine();//先听客户端发送的信息,这里同样会阻塞

  System.out.println(info);

          //发送信息给客户端

  writer.println("你好!客户端");    writer.flush();

  info=reader.readLine(); System.out.println(info);

  writer.println("再见!客户端");   writer.flush();

  socket.close();//关闭与客户端的连接

}catch(Exception e){ e.printStackTrace(); } } }

public static void main(String[] args){ System.out.println("服务器启动中……");

ServerDemo demo=new ServerDemo(); demo.start(); }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值