基于Socket的java网络编程

1.了解TCP和UDP两类传输协议
2.基于Socketjava网络编程
3.通过Socket实现文件传输
4.支持多客户端的Client/Server程序
5.Datagram通讯

传统的网络编程是一项非常细节化的工作,程序员必须处理和网络有关的大量细节,如各种协议,甚至要理解网络相关的硬件知识。而 Java 则将底层的网络通信细节予以屏蔽,使得使用的编程模型是一个文件模型,也就是说, 可以象操作流一样来操作网络数据传输
     另外,由于在网络连接中,通常都需要一个服务器同时为多个客户端服务,因此 Java 的多线程机制也大派用场。

事实上网络编程简单的理解就是两台计算机相互通讯数据而已。对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了。Java SDK提供一些相对简单的API来完成这些工作,Socket就是其中之一。对于Java而言。这些API存在于 java.net 这个包里面。因此只要导入这个包就可以准备网络编程了。
网络编程的基本模型就是 客户机到服务器 (C/S) 模型。
简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置( 服务器 ),而另一个( 客户端 )则只需要知道这个固定的位置。并去建立两者之间的联系,然后完成数据的通讯就可以了。这里提供固定位置的通常称为服务器,而建立联系的通常叫做客户端。基于这个简单的模型,就可以进入网络编程啦

什么是Socket?
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程接口
一个 Socket 由一个 IP 地址和一个端口号唯一确定
但是,Socket所支持的协议种类也不仅TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。


Socket通讯的过程
1. Server端Listen(监听)某个端口是否有连接请求
2. Client端向Server 端发出Connect(连接)请求
3. Server端向Client端发回Accept(接受)消息,一个连接就建立起来了。
4. Server端和Client 端都可以通过Send,Write等方法与对方通信。


Socket通讯的过程
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:

  (1)创建Socket;
  (2)打开连接到Socket的输入/出流;
  (3)按照一定的协议对Socket进行读/写操作;
  (4)关闭Socket。


创建Socket
      java在包java.net中提供了两个类 Socket ServerSocket ,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下:
Socket(String host, int port);
    Socket(InetAddress address, int port);
    其中address、host和port分别是双向连接中另一方的IP地址、主机名和端口号


注意
在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。 1~1024 的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时, 最好选择一个大于 1023 的数以防止发生冲突
  在创建socket时如果发生错误,将产生IOException在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出异常。





简单的Client/Server程序—客户端程序:

// 得到本机的IP地址
InetAddress addr = InetAddress.getByName(null);
System.out.println("Address = " + addr);
// 服务器的地址和端口号
Socket socket = new Socket(addr, JabberServer.PORT);
try {
//[addr=对方地址,port=对方端口号,localport=本机端口号,会不断变化]
System.out.println("Client Socket = " + socket);
// 与服务器端代码相同,连接成功以后就是对等关系
BufferedReader in = new BufferedReader(new
                        InputStreamReader(socket.getInputStream()));
// 向socket写,自动清除缓存
PrintWriter out = new PrintWriter(new BufferedWriter(new 
               OutputStreamWriter(socket.getOutputStream())), true);
for (int i = 0; i < 10; i++) {
// 向socket写表示向服务器端发送数据
out.println("howdy " + i);
// 从服务器端收数据
String str = in.readLine();
System.out.println(str);
}
out.println("END");
} finally {
System.out.println("closing...");
socket.close();
}


// 只指定了端口号,没IP地址,因为它正执行在程序所在的机器上
ServerSocket server = new ServerSocket(PORT);
// 输出结果:[addr=对方地址,port=对方端口号,localport=本机端口号]
System.out.println("Started: " + server);
Socket socket = null;
try {
socket = server.accept(); // 堵塞状态,直到有一个连接
System.out.println("Connection accepted: " + socket);
// 连接成功后开始操作从socket中得到输入流读数据(接收从网络传过来的数据)
BufferedReader in = new BufferedReader(new
       InputStreamReader(socket.getInputStream()));
// 写出,自动清除缓存
PrintWriter out = new PrintWriter(new BufferedWriter(new
    OutputStreamWriter(socket.getOutputStream())), true);
// 循环输出数据直接遇到END字符
while (true) {
String data = in.readLine();
if ("END".equals(data))
break;
System.out.println("Echoing: " + data);
// 向客户端发送数据
out.println(data);
}
} finally {
socket.close();    // 保证服务器被关闭
server.close();
}

完成刚刚的实例,实现服务器与客户端的通信..


支持多客户的client/server程序
前面的Client/Server程序只能实现Server和一个客户的对话。在实际应用中,往往是在服务器上运行一个永久的程序,它可以接收来自其他多个客户端的请求,提供相应的服务。
为了实现在服务器方给多个客户提供服务的功能,需要对上面的程序进行改造,利用多线程实现多客户机制。
服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,服务器就会启动一个专门的服务线程来响应该客户的请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。

Datagram通讯
在TCP/IP协议的传输层除了TCP协议之外还有一个UDP协议,相比而言UDP的应用不如TCP广泛,几个标准的应用层协议HTTP、FTP、SMTP使用的都是TCP协议。但是,UDP协议可以应用在需要很强的实时交互性的场合,如网络游戏,视频会议等。
1. 什么是Datagram
数据报(Datagram)就跟日常生活中的邮件系统一样,是不能保证可靠的寄到的,而面向链接的TCP就好比电话,双方能肯定对方接受到了信息。
TCP: 可靠,传输大小无限制,但是需要连接建立时间,差错控制开销大。
UDP: 不可靠,差错控制开销较小,传输大小限制在64K以下,不需要建立连接。

2. Datagram使用
       包java.net中提供了两个类 DatagramSocket DatagramPacket 用来支持数据报通信,DatagramSocket用于在程序之间建立传送数据报的 通信连接 ,DatagramPacket则用来表示一个 数据报
DatagramSocket的构造方法:
DatagramSocket();
DatagramSocket(int port);
DatagramSocket(int port, InetAddress laddr)
其中,port指明socket所使用的端口号,如果未指明端口号,则把socket连接到本地主机上一个可用的端口。laddr指明一个可用的本地地址。给出端口号时要保证不发生端口冲突,否则会生成SocketException类例外。
注意:上述的两个构造方法都声明抛弃非运行时例外SocketException,程序中必须进行处理,或者捕获、或者声明抛弃。

用数据报方式编写client/server程序时,无论在客户方还是服务方,首先都要建立一个DatagramSocket对象,用来接收或发送数据报,然后使用DatagramPacket类对象作为传输数据的载体。
DatagramPacket的构造方法:
DatagramPacket(byte buf[], int length);
DatagramPacket(byte buf[], int length, InetAddress addr, int port);
DatagramPacket(byte[] buf, int offset, int length);
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port);

其中,buf中存放数据报数据,length为数据报中数据的长度,addr和port指明目的地址,offset指明了数据报的位移量。
在接收数据前 ,应该采用上面的第一种方法生成一个DatagramPacket对象,给出接收数据的缓冲区及其长度。然后调用DatagramSocket 的方法 receive() 等待数据报的到来,receive()将一直等待,直到收到一个数据报为止。
DatagramPacket packet=new DatagramPacket(buf, 256);
Socket.receive (packet);

发送数据前 ,也要先生成一个新的DatagramPacket对象,这时要使用上面的第二种构造方法,在给出存放发送数据的缓冲区的同时,还要给出完整的目的地址,包括IP地址和端口号。发送数据是通过DatagramSocket的方法 send()实现的,send()根据数据报的目的地址来寻径,以传递数据报。
DatagramPacket packet=new DatagramPacket (buf, length, address, port);
  Socket.send(packet)
在构造数据报时,要给出InetAddress类参数。类InetAddress在包java.net中定义,用来表示一个Internet地址,我们可以通过它提供的类方法getByName()从一个表示主机名的字符串获取该主机的IP地址,然后再获取相应的地址信息。



这些内容比较复杂、需要大家多思考,多操作慢慢理解...



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值