网络编程

来源:互联网 发布:投屏软件 编辑:程序博客网 时间:2024/05/17 11:57

    计算机网络就是实现了多个计算机互联的系统,相互连接的计算机之间彼此能够进行数据交换。

11.1网络编程的基础知识
    IP地址只能保证把数据送到该计算机,但不能保证把这些数据交给哪个网络程序,因此,每个被发送的网络数据包的头部都包含有一个称为“端口”的部分,它是一个整数,用于表示该数据帧交给哪个应用程序来处理。

UDP与TCP:
TCP(Transmission Control Protocol,简称TCP)传输控制协议。
UDP(User Datagram Protocol,简称UDP)用户数据报协议。
TCP是面向连接的通信协议,TCP提供两台计算机之间的可靠无差错的数据传输。
UDP是面向无连接的通信协议,UDP不保证可靠数据的传输,但能够向若干个目标发送数据,接收发自若干个源的数据。

Socket
    可以把Socket比喻成是一个港口码头。应用程序只要把货物放到港口码头上,就算完成了货物的运送。应用程序只需等待货物到达码头后,将货物取走。
    在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和Port。
   
     Java分别为UDP和TCP两种通信协议提供了相应的编程类,这些类存放在java.net包中,与UDP对应的是DatagramSocket,与TCP对应的是ServerSocket(用于服务器端)和Socket(用于客户端)。
ServerSocket类用于TCP通信的服务器端。
Socket类用于TCP通信的服务器和客户端。

11.2 Java编写UDP网络程序
DatagramSocket
构造函数:
public DatagramSocket()
public DatagramSocket(int port)
public DatagramSocket(int port,InetAddress laddr)
    用第一个构造函数创建DatagramSocket对象,没有指定端口号,系统就会分配一个还没有被其他网络程序所使用的端口号。用第二个构造函数创建DatagramSocket对象,可以指定自己想要的端口号。用第三个构造函数创建DatagramSocket对象,除了指定自己想要的端口外,还可以指定相关的IP地址,这种情况适用于计算机上有多块网卡和多个IP的情况,我们可以明确规定我们的数据通过哪块网卡向外发送的接收哪块网卡收到的数据。
    如果程序不再使用某个Socket,我们应该调用DatagramSocket.close()方法,关闭这个Socket,通知驱动程序释放为这个Socket所保留的资源,系统就可以将这个Socket所占用的端口号重新分配给其他程序使用。

在发送数据时,用DatagramSocket.send()方法,格式如下:
public void send(DatagramSocket p)
在接收数据时,用DatagramSocket.receive()方法,格式如下:
public void receive(DatagramSocket p)
send()和receive()方法都需要我们传递一个DatagramSocket类的实例对象。


DatagramPacket
    如果把DatagramSocket比作创建的港口码头,那么DatagramPacket就是发送和接收数据的伪装箱。
构造函数主要形式:
public DatagramPacket(byte[] buf,int length)
public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
    在接收数据时,我们是没法事先就知道哪个地址和端口的Socket会发来数据,就像我们要准备一个集装箱去接收发给我们的货物时,是不用标明发货人或是收货人的地址信息的,所以应该用每个构造函数来创建接收数据的DatagramPacket对象。在发送数据时,我们必须指定接收方Socket的地址和端口号,就像我们要发送数据的集装箱上面必须标明接收人的地址信息一样,所以应该用第二个构造函数来创建发送数据的DatagramPacket对象。

DatagramPacket类一些方法介绍:
    getInterAddress和getPort方法,当接收方接收到网络上发送的信息,可以使用这两个方法获得发送方的IP地址和端口号。
    getData和getLength方法,返回数据缓冲区和返回将要发送或接收到的数据的长度。

InetAddress
    这个类是用来表示计算机地址的。
    getByName() 这个静态方法能够根据我们的条件返回一个InetAddress类的实例对象。
    getHostAddress方法能够以字符串的形式返回InetAddress对象中的IP地址。

用UDP编写网络聊天程序
过程:
1.编写图形用户界面;
2.编写网络消息发送功能;
3.编写网络消息接收功能。
注意:只有UdP程序才能发送和接收广播地址数据。


11.3 Java编写TCP网络程序
    利用UDP通信的两个程序是平等的,没有主次之分,两个程序代码可以是完全一样的。而利用TCP协议进行通信的两个应用程序,是有主从之分的,一个称为服务器程序,另外一个称为客户机程序,两者的功能和编写方法大不相同。
TCP网络程序通信过程:
1.服务器程序创建一个ServerSocket,然后调用accept方法等待客户来连接。
2.客户端程序创建一个Socket并请求与服务器建立连接。
3.服务器接收客户的连接请求,并创建一个新的Socket与该客户建立专线连接。
4.刚才建立了连接的两个Socket在一个单独的线程(由服务器程序创建)上对话。
5.服务器开始等待新的连接请求。


ServerSocket类
构造函数有如下几种形式:
public serverSocket()
public serverSocket(int port)
public serverSocket(int port,int backlog)
public serverSocket(int port,int backlog,InetAddress bindAddr)
    用第一个构造函数创建ServerSocket对象,没有与任何端口号绑定,不能直接使用,还要继续调用bind方法,才能完成其他构造函数所完成的功能。
    用第二个构造函数创建ServerSocket对象,就可以将这个ServerSocket绑定到一个指定的端口上。端口号可以设置为0,由系统自动分配没被占用的端口号。但这并不常用。
    用第三个构造函数创建ServerSocket对象,就是在第二个构造函数的基础上,根据backlog参数指定,在服务器忙时,可以与之保持连接请求的等待客户数量,对于第二个构造函数,没有指定这个参数,则使用默认的数量,大小为50。
    用第四个构造函数创建ServerSocket对象,除了指定第三个构造函数中的参数外,还可以指定相关的IP地址,这种情况适用于计算机上有多块网卡和多个IP的情况,可以明确规定ServerSocket在哪块网卡或IP地址上等待客户的连接请求。

Socket类
    客户端要与服务器建立连接,首先必须创建一个Socket对象。
Socket类的构造函数有如下几种形式:
public socket()
public socket(String host,int port)
public socket(InetAddress address,int port)
public socket(String host,int port,InetAddress localAddr,int localport)
public socket(InetAddress address,int port,InetAddress localAddr,int localport)
    用第一个构造函数创建Socket对象,不与任何服务器建立连接,不能被直接使用,需要调用connect方法,才能完成和其他构造函数一样的功能。如果想用同一个Socket对象去轮循连接多个服务器,可以使用这个构造函数创建Socket对象后,再不断调用connect方法去连接每个服务器。
    用第二个和第三个构造函数创建Socket对象后,会根据参数去连接在特定地址和端口上运行的服务器程序,第二个构造函数接收字符串格式的地址,第三个构造函数接收InetAddress对象所包装的地址。
    第四和第五个构造函数在二、三的基础上,还指定了本地Socket所绑定的IP地址和端口号,由于客户端的端口号的选择并不重要,所以一般情况下,不会使用这两个构造函数。

    当客户端和服务器端的两个Socket建立了专线连接后,连接的一端能向另一端连续写入字节,也能从另一端连续读入字节,也就是建立了专线连接的两个Socket是以IO流的方式进行数据交换的,Java提供了Socket.getInputStream方法返回Socket的输入流对象,Socket.getOutputStream方法返回Socket的输出流对象。只要连接的一端向该输出流对象写入了数据,连接的另一端就能从其输入流对象中读取到这些数据。

注意:关闭数据流要注意先后顺序,基本是与建立时相反。
telnet程序可以被很好地用作测试TCP服务器功能的TCP客户端程序,例子:
telnet 127.0.0.1 8000

TCP服务器程序模型的编写要点:
1.TCP服务器程序要想能接收多个客户端连接,需要循环调用ServerSocket.accept方法。
2.服务器程序与每个客户端连接的会话过程不能互相影响,需要在独立的线程中运行。
3.一个线程服务对象与一个服务器端Socket对象相关联,共同来完成与一个客户端的会话。

如何检测和解决端口冲突问题
·使用netstat命令查看当前正在被使用的TCP端口号。
·通过一个配置参数来指定TCP服务程序所使用的端口号。
·将用户所指定的端口号保存到一个文件中,当服务器程序下次启动运行时,直接  从文件中读取那个端口号。


怎样理解应用程序协议和网络通信协议的关系?
    我们把TCP协议比作电话,把各种网络应用协议(ftp、smtp、pop3、http等)就可以比做是各种语言。就像我们的语言不一定非要通过电话系统传递一样的道理,我们的应用程序协议也可以在其他的网络通信协议(非TCP协议)上传送。


访问Internet网络资源
    java.net包中还有URL、URLDecoder、URLEncoder、URLConnection、HttpURLConnection等类。

URL(Uniform Resource Locator,简称URL)统一资源定位符。
·URL的基本组成:协议、主机名、端口号、资源名。
·相对URL,例如"/a.html"、"./a.html"、"../../a.html"、"a.html"。
·URL编码规则:
  -将空格转换为加号(+)。
  -对0-9,a-z,A-Z之间的字符保持不变。
  -对于所有其他的字符,用这个字符的当前字符集编码在内存中的十六进制格式   表示,并在每个字节前加上一个百分号(%)。
  -对于空格也可以直接使用其十六进制编码方式。
HTTP请求消息
    一个完整的请求消息包括:一个请求行、若干消息头、以及实体内容。
HTTP响应消息
    一个完整的响应消息包括:一个状态行、若干消息头、以及实体内容。
了解几个HTTP消息头:
Connection
    用于指定处理完本次请求/响应后,客户端与服务器是否继续保持连接。设置值可以为Keep-Alive和close。
Accept-Language
    用于指出客户机期望服务器返回的文档所使用的国家语言,可以指定多个以逗号分隔的国家语言。
Content-Length
    用于表示实体内容的长度(字节数)。
Range
    用于指定服务器只需返回文档中的部分内容及内容范围,有以下几种使用格式    :
1.Range:bytes=100-599
2.Range: bytes=100-
3.Range: bytes=-100
Content-Range
    用于指定服务器返回的部分实体内容的位置信息,例如,Content-Range:bytes 2543-4532/7898

URL类
构造函数(都可引发MalformedURLException异常):
-public URL(String spec)
-public URL(String protocol,String host,int port,String file)
-public URL(String protocol,String host,int port,String file,URLStreamHandler handler)
-public URL(URL context,String spec)

工厂设计模式
*URL类的setURLStreamHandlerFactory(URLStreamHandlerFactory fac)静态方法。
*StreamHandlerFactory类的createURLStreamHandler(String protocol)方法。


URLConnection与HttpURLConnection类
    一个HTTP连接可以被多个HttpURLConnection实例对象共享,调用HttpURLConnection的disconnect方法可以关闭底层共享网络。

原创粉丝点击