java网络编程

UDP协议:无连接的通信协议。

TCP协议:面向连接的通信协议。  (可靠与否是由是否发送回答与是否丢失重传等机制完成)

1. Socket是网路驱动层提供给应用程序的接口和一种机制。
    可以把Socket比喻成是一个港口码头。应用程序只要把货物放到码头,就算完成了货物的运送;应用程序只需等待货物到达码头后,将货物取走。
    Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和Port。
        
 
UDP程序编写:(一般发送端需要指定接收方的IP和Port,)
1. DatagramSocket类 
    send(DatapramPacket dp),receive(DatapramPacket dp)方法
2. DatapramPacket类 
   在DatapramPacket类中包装了Ip,Port,data。
3. InetAddress类
public class UdpSend{
    public static void main(String[] args) throws Exception{
        //创建发送方的Socket对象
        DatagramSocket client=new DatagramSocket();
        String str="hello 车江涛";  //要发送的数据
        //发送数据(并且在发送方DatagramSocket对象中指定接收方的IP和Port)
        //插入中文(length为字节数组的长度而不是字符的长度)
        client.send(new DatagramPacket(str.getBytes(),str.getBytes().length,InetAddress.getByName("192.168.78.1"),10000));  
//        client.send(new DatagramPacket(str.getBytes(),str.length(),InetAddress.getByName("192.168.78.1"),10000));  
        client.close();
    }
}

public class UdpRecv {
    public static void main(String[] args) throws Exception {
        //才创建接收端的Socket对象(必须指定接收的端口号)
        DatagramSocket server = new DatagramSocket(10000);
        byte[] buf=new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf, 1024);  
        //接收数据到dp中(正常情况直到接收到程序才往下执行,不然会阻塞到此)
        server.receive(dp);  
        String result=new String(dp.getData(),0,dp.getLength());
        String clientIp=dp.getAddress().getHostAddress();
        int clientPort=dp.getPort();
        System.out.println(clientIp+":"+clientPort+"  内容是:"+result);
        server.close();
    }
}

 总结:利用UDP通信的两个程序是完全平等的,没有主从之分,可以完全是同一个程序的两个运行实例。而利用TCP是有主从之分,是有客户端和服务端之分,两者程序的编写大不一样。

TCP编程:

 

1. ServerSocket类

    accept()方法等待客户端的链接,并且放回一个与客户端建立了链接的Socket对象,服务器端的Socket对象一般不用new实例化Socket。

2. Socket类:如果没有指定参数则不能直接使用,需要使用connection()方法。

一旦客户端与服务器端的Socket建立链接就以字节流(输入流、输出流)的形式进行网络交换。如果一段向自己的输入字节流中写入了数据,另一方就能通过自己的输出流中读取到数据。

 使用BufferedReader包装类,从网络输入流中一个读取一行文本。

public static void main(String[] args) throws Exception{
        ServerSocket server = new ServerSocket(10001);
        //如果在accept在没有接收到客户端对象之前没有阻塞,说明在这之前程序出了错误(比如:用了一个已经被占用的端口)
        Socket s= server.accept();
        InputStream in = s.getInputStream(); //得到客户端给服务器的输入
        OutputStream out=s.getOutputStream(); //给客户端的数据
        out.write("hello cjt".getBytes());
        /*byte[] buf=new byte[1024];
        int len = in.read(buf); //由于read只要一读到数据就返回,则可以使用BufferedReader类完成整行读取
        System.out.println(new String(buf,0,len));*/
        
        BufferedReader bf = new BufferedReader(new InputStreamReader(in)); //关闭了包装类就关闭了内部所包装的对象
        String result = bf.readLine();
        System.out.println(result);
        in.close(); out.close();
        s.close();
        server.close();
    }    


InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(in));
PrintWriter pw=new PrintWriter(out,true);   //IO流中可能有缓冲区,不一定在遇到\n后刷新缓冲区将数据直接写到网络上。
//得到客户端给服务器的输入
String result=br.readLine();
pw.println(result.toUpperCase());    //abd{backspace}c  abc c{backspace}dba  dba(所以在网络中一般不能单独靠打印的结果判断程序的正确性,而应特殊处理(编码))

TCP服务程序模型编程要点:
1. TCP服务程序要想与多个客户端建立链接,需要循环调用accept方法;

2. 服务器程序与每个客户端程序链接的会话过程不能相互影响,需要在独立的线程中运行。

3. 一个线程服务对象与一个服务器端Socket对象相关联,共同来完成于一个客户端的会话。

 如何检测和解决TCP端口号的冲突问题:(通过一个配置参数来指定TCP服务程序所使用的端口号)

TCP客户端程序的编写:

Socket client=new Socket("192.168.78.1", 10006);
InputStream in=client.getInputStream();  //从网络上读取数据
OutputStream out=client.getOutputStream(); //向网络上发送数据
BufferedReader br = new BufferedReader(new InputStreamReader(in));  //为了一次从网上读取一行数据,将InputStream对象进行包装
PrintWriter pw = new PrintWriter(out,true); //将输出到网络上的数据进行包装
BufferedReader brBoard=new BufferedReader(new InputStreamReader(System.in));  //从键盘读取数据
boolean isRunning=true;
while(isRunning){
    String fromBoard=brBoard.readLine();
    pw.println(fromBoard);  //将数据发送到网络
    String fromNet=br.readLine();  //接收从网上传回来的数据
    System.out.println(fromNet);
}


在TCP网络上传递对象:

ObjectInputStream和ObjectOutputStream可以从输入流读取对象类型和将对象类型的数据写入到底层输出流。使用ObjectInputStream和ObjectOutputStream来包装底层网络字节流,TCP服务器和TCP客户端之间就可以传递对象类型的数据。

ObjectInputStream ois=new ObjectInputStream(in); //将得到的数据用ObjectInputStream对象包装
Student s = (Student)ois.readObject();

Student s=new Student("chejt",20);
ObjectOutputStream oos=new ObjectOutputStream(out);
oos.writeObject(s);

应用程序协议和网络通信协议的关系。   FTP协议和TCP协议
ASP、JSP与网络编程的关系。    卫星与网络电视

访问Internet网络资源:

   URL的基本组成: 协议、主机名、端口号、资源名

   URL编码与解码

URL类:本身并不能直接访问URL的具体数据。

URLConnection类:才能获得URL指定的具体的数据。 HttpURLConnection

        URLConnection:并不是以创建就立刻与远程资源建立链接,而是在调用get响应方法时彩玉远程资源建立链接,在这之前可以设置各种头请求的头信息。

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

工厂模式:当不知道一个类有几个具体子类或不想让其他人直到如何创建该类对象时,可以考虑工厂模式。

HTTP协议的会话过程:    HTTP消息:包括状态行,若干消息头,实体内容。   (描述信息的信息成为元信息) 

消息头中常用的: 

     Connection:用于指定处理完本次请求/响应之后,客户端与服务器是否继续保持连接。

     Accept-Language:用于指出客户端需要服务器返回的文档的语言类型。

     Content-Length:用于指定表示实体内容的长度(字节数(为了区分在同一次链接中区分多次请求的数据))。

     Range:用于指定服务器只需返回文档中的部分内容及其范围

   

 

Http协议1.0中根据一个URL地址都要建立一次Htpp链接,传输完该数据之后链接断开,这样影响客户机和服务器的性能。Http1.1可以再一次链接中传输多个文件(一个网页中的图片)  
 

 

posted @ 2014-09-25 20:14  cjt1991  阅读(181)  评论(0编辑  收藏  举报