Socket网络编程

在java编程过程中,我们常常会遇到需要在客户端和服务器之间进行通信的需求,那就需要使用Socket了。Socket套接字在 java.net.Socket 包下。

1 、网络通信模型

(1)C/S: client/server,客户端/服务器端;服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,客户端需要安装专用的客户端软件。

(2) B/S: browser/server,浏览器端/服务器端; 客户机上只要安装一个浏览器(Browser),服务器安装Oracle、Sybase或 SQL Server等数据库。在这种结构下,用户界面完全通过WWW浏览器实现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现。浏览器通过Web Server同数据库进行数据交互。

(3)C/S 与 B/S 区别
①硬件环境不同: 
  C/S 一般建立在专用的网络上, 小范围里的网络环境, 局域网之间再通过专门服务器提供连接和数据交换服务.
  B/S 建立在广域网之上的, 不必是专门的网络硬件环境,例与电话上网, 租用设备. 信息自己管理. 有比C/S更强的适应范围, 一般只要有操作系统和浏览器就行 
②对安全要求不同 
  C/S 一般面向相对固定的用户群, 对信息安全的控制能力很强. 一般高度机密的信息系统采用C/S 结构适宜. 可以通过B/S发布部分可公开信息.
  B/S 建立在广域网之上, 对安全的控制能力相对弱, 可能面向不可知的用户。
③对程序架构不同 
  C/S 程序可以更加注重流程, 可以对权限多层次校验, 对系统运行速度可以较少考虑.
  B/S 对安全以及访问速度的多重的考虑, 建立在需要更加优化的基础之上. 比C/S有更高的要求 B/S结构的程序架构是发展的趋势, 从MS的.Net系列的BizTalk 2000 Exchange 2000等, 全面支持网络的构件搭建的系统. SUN 和IBM推的JavaBean 构件技术等,使 B/S更加成熟. 
④软件重用不同 
  C/S 程序可以不可避免的整体性考虑, 构件的重用性不如在B/S要求下的构件的重用性好.
  B/S 对的多重结构,要求构件相对独立的功能. 能够相对较好的重用.就入买来的餐桌可以再利用,而不是做在墙上的石头桌子 
⑤系统维护不同 
  C/S 程序由于整体性, 必须整体考察, 处理出现的问题以及系统升级. 升级难. 可能是再做一个全新的系统
  B/S 构件组成,方面构件个别的更换,实现系统的无缝升级. 系统维护开销减到最小.用户从网上自己下载安装就可以实现升级. 
⑥处理问题不同 
  C/S 程序可以处理用户面固定, 并且在相同区域, 安全要求高需求, 与操作系统相关. 应该都是相同的系统
  B/S 建立在广域网上, 面向不同的用户群, 分散地域, 这是C/S无法作到的. 与操作系统平台关系最小. 
⑦用户接口不同 
  C/S 多是建立的Window平台上,表现方法有限,对程序员普遍要求较高
  B/S 建立在浏览器上, 有更加丰富和生动的表现方式与用户交流. 并且大部分难度减低,减低开发成本. 
⑧信息流不同 
  C/S 程序一般是典型的中央集权的机械式处理, 交互性相对低
  B/S 信息流向可变化, B-B B-C B-G等信息、流向的变化, 更像交易中心。

2、使用ServerSocket创建TCP服务器端

ServerSocket:接受其他通信实体连接请求的类,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状态。ServerSocket包含一个监听来自客户端连接请求的方法:

Socket accept():如果接受到一个客户端的连接请求,该方法将返回一个与客户端Socket对应的Socket,否则该方法将一直处于等待状态,线程也被阻塞。

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

为了创建ServerSocket对象,ServerSocket类提供了如下几个构造器:

(1)ServerSocket(int port):用指定的端口port来创建一个ServerSocket。该端口为一个有效的端口整数值:1~65535

(2)ServerSocket(int port,int backlog):增加一个用来改变连接队列长度的的参数backlog

(3)ServerSocket(int port,int backlog,InetAddress localAddr):在机器存在多个IP地址的情况下,允许通过localAddr这个参数来指定将ServerSocket绑定到指定的IP地址

ServerSocket使用完毕,应使用ServerSocket的close()方法来关闭该ServerSocket

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

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

3、使用Socket进行通信

Socket:封装着本地的地址,服务端口等信息。 

客户端通常可使用Socket的构造器来连接指定的服务器,Socket有如下两个构造器:

(1)Socket(InetAddress/String remoteAddress,int port):创建连接到指定远程主机、远程端口的Socket,该构造器没有指定本地地址、本地端口,默认使用本地主机的IP地址或系统动态指定的IP地址

(2)Socket(InetAddress/String remoteAddress,int port,InetAddress localAddr,int localPort):创建连接到指定远程主机,远程端口的Socket,并指定本地IP地址和本地端口号,适用于本地主机有多个IP地址的情况

当客户端、服务器产生了对应的Socket后,程序无需再区分客户端和服务器,而是通过各自的Socket进行通信。Socket提供如下两个方法来获取输入流和输出流:

(1)InputStream getInputStream():返回该Socket对象对应的输入流,让程序通过该输入流从Socket中取出数据

(2)OutputStream getOutputStream():返回该Socket对象对应的输出流,让程序通过该输出流向Socket中输出数据

4、建立连接并向服务器发送信息步骤: 

(1)通过服务器的地址及端口与服务器连接,而创建 Socket 时需要以上两个数据。

(2)连接成功后可以通过 Socket 获取输入流和输出流, 使用输入流接收服务端发送过来的信息。

(3)关闭连接。

Socket 连接基于 TCP/IP 协议,是一种长连接(长时间连着)。永远都是 Socket 去主动连接 ServerSocket。一个ServerSocket可以接收若干个 Socket的连接。网络通信的前提: 一定要捕获异常。

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

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

5、Socket编程实例

服务器:

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class server {
	
	public static void main(String[] args) throws IOException{
		
		ServerSocket ss = new ServerSocket(30000);
		while(true){
			Socket s = ss.accept();
			PrintStream ps = new PrintStream(s.getOutputStream());
			ps.println("您好,您收到了服务器的祝福!");
			ps.close();
			s.close();
		}		
	}
}

客户端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class client {
	
	public static void main(String[] args) throws IOException{
		
		Socket s = new Socket("127.0.0.1",30000);
		s.setSoTimeout(10000);
		BufferedReader br = new BufferedReader(
				new InputStreamReader(s.getInputStream())
				);
		String line = br.readLine();
		System.out.println("来自服务器的数据:" + line);
		br.close();
		s.close();
	}
}
先启动服务器,再运行客户端,运行结果如下:





  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值