java网络通讯(UDP与TCP)

来源:互联网 发布:js 数组长度 编辑:程序博客网 时间:2024/05/19 04:07

什么是计算机网络

通俗讲:两台电脑连在一起就组成了一个计算机网络。我们通过光钎连接到电信的网关,中国电信通过海底光缆和美国电信网关连接,你就是和全世界的在线用户连着。

网络编程就是在两个或连个以上的设备之间传输数据

什么是网络通信协议

网络通信协议就像我们的中文一样,她就是我们之间的共同语言,他规定了我们之间怎么说话,我先说什么你再说什么,你怎么说,而我怎么听。而网络通信得先规定一些俗称的网络通信协议,先说好,两台计算机之间什么收发信息,信息格式是什么,信息怎么发,怎么接受,而万一出错怎么办怎么处理。

UDP和TCP

TCP和TCP都是传输层协议

网络应用中基本上都是TCP和UDP,TCP是面向连接的通信协议,UDP是无连接的通信协议。

TCP协议特点

传输控制协议,提供的是面向连接,可靠的字节流服务。

当客户和服务器彼此交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据。

TCP提供超时重发,丢弃数据,检验数据,流量控制等功能,保证数据能从一端到另一端。


UDP协议特点

UDP不提供可靠性,它只能把应用程序传给IP层的数据包发送出去,但是并不能保证他们能到达目的地。

UDP传输数据时是有大小限制的,每一个被传输的数据包必须限定在64kB之内。

由于UDP在传输数据报前不用再客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

应用

TCP通信在网络上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的宽带,因此TCP传输的效率不如UDP高。

UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中Client/sever 应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。


127.0.0.1是回路地址,用于测试,相当于localhost本机地址,没有网卡,不设DNS都可以访问.

端口地址在0~65535之间,其中0~1023之间的端口是用于一些知名的网络服务和应用,用户的普通网络应用程序应该使用1024以上的端口.

Socket连接套接字,java分别为TCP和UDP提供了相应的类,TCP是java.net.ServerSocket(用于服务器端)和java.net.Socket(用于客户端);UDP是java.net.DatagramSocket.

Java编写UDP网络程序

相关类介绍:

DatagramSocket

有如下构造方法

1.DatagramSocket():构造数据报套接字并将其绑定到本地主机上任何可用的端口

2.DatagramSocket(int port);创建数据报套接字并将其绑定到本地主机上的指定端口。

3.DatagramSocket(int port,InetAddressladdr):创建数据报套接字,并将其绑定到指定的本地地址。即指定网卡发送和接受数据。

如果在创建DatagramSocket对象是,没有指定网卡的IP地址,在发送数据时,底层驱动程序会自动选择一块网卡去发送,在接收数据时,会接收所有的网卡收到的与端口一致的数据

发送信息时,可以不指定端口号,接收信息时,要指定端口号,因为接收指定的数据。

发送数据使用DatagramSocket.send(DatagramPacketp)方法;

接收数据使用DatagramSocket.receive(DatagramPacketp)方法;

DatagramPacket

Datagrampacket类有如下构造方法:

1.     DatagramPacket(byte[]buf,int length);//构造DatagramPacket,用来接收长度为length的数据包。

2.     DatagramPacket(byte[] buf,intlength,InetAddress address,int port);构造数据报,将长度为length的包发送到指定主机上的指定端口。

接收数据时,第一种构造方法,发送数据时使用第二种构造方法


InetAddress

Java中对Ip地址进行包装的类,。DatagramPacket.getAddress()可以获取发送或接收方的IP地址,DatagramPacket.getPort()可以获取发送或接受方的端口


UDP程序例子

发送数据代码:


接收数据代码


Java编写TCP网络程序

ServerSocket

编写TCP网络服务程序,首先要用到java.net.ServerSocket类型泳衣创建服务器Socket它的常用构造方法有:

1.     ServerSocket(int port):创建绑定到指定端口的服务器套接字。

2.     ServerSocket(int port, intbacklog):利用指定的backlog(服务器忙时保持连接请求的等待客户数量),创建服务器套接字并将其绑定到指定的本地端口号

3.     ServerSocket(int port,intbacklog,inetAddress bindaddr):使用指定的端口、侦听backlog 和要绑定到的本地IP地址创建服务器。

Socket

客户端要与服务器建立连接,必须先创建一个Socket对象,它的常用构造方法有:

1.     Socket(Stringhost,int port):创建一个流套接字并将其连接到指定主机上的指定端口号。

2.     Socket(InetAddress address,intport):创建一个流套接字并将其连接到指定IP地址的指定端口号。

3.     Socket(InetAddress address,intport,Inetaddress localAddr,int localPort):创建一个套接字并将其连接到指定远程端口上的指定远程地址。

4.     Socket(Stringhost,int prot,InetAddress localAddr,int localPort):创建一个套接字并将其连接到指定远程主机上的指定远程端口。

对于通常情况的应用,使用第一个构造方法来创建Socket对象,并与服务器建立连接,是非常简单和方便的

 

服务器程序调用ServerSocket.accept方法等待客户端的连接请求,一旦accept接收了客户端连接请求,该方法返回一个与该客户建立了专线连接的Socket对象,不用程序去创建这个Socket对象,建立了连接的两个Socket是IO流的方式进行数据交换的,java提供了Socket.getInputStream返回Socket的输入流对象,socket.getOutputStream返回Socket 的输出流对象。


大多数情况下,服务器都要服务多个客户端,但一次accept方法只接受一个连接,因此要把accept方法放在一个循环语句中,这样就可以接收多个连接,每个连接的数据交换代码也放在一个循环中,这样才能保证两者可以不听的交换数据。

每个连接的数据交换代码必须放在独立的线程中运行,否则这段代码运行期间,就没法执行其他的程序代码,accept方法也得不到调用,进的连接无法进入。

例子

服务器代码:

import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class TcpServer {public static void main(String[] args) throws Exception {//建立服务器ServerSocket ss=new ServerSocket(7000);while(true){//与客户端建立连接Socket s=ss.accept();//创建匿名类对象,并启动此对象的一个线程new Thread(new Servicer(s)).start();}}};//建立Servicer类class Servicer implements Runnable{Socket s;//得到Socket类的引用s//创建构造方法public Servicer(Socket s) {this.s=s;}//重写run()方法启动线程@Overridepublic void run() {try {//得到输入输出流InputStream ips=s.getInputStream();OutputStream ops=s.getOutputStream();//将字节流转换成字符流并使用BuffeedReader读取,碰到换行才结束BufferedReader br=new BufferedReader(new InputStreamReader(ips));//读不同的数据类型DataOutputStream dos=new DataOutputStream(ops);while(true){//按行读取客户端输入的内容String strWord=br.readLine();//判断内容是否为quit,如果是结束循环if(strWord.equalsIgnoreCase("quit")){break;}//将得到的字符串转换为StringBuffer并且反转,最后变为String存入strEcho中String strEcho=new StringBuffer(strWord).reverse().toString();//将内容写给客户端dos.writeBytes(strWord+"------>"+strEcho+System.getProperty("line.separator"));}br.close();dos.close();s.close();} catch (IOException e) {e.printStackTrace();}}}

客户端代码


import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;public class TcpClient {public static void main(String args[]) throws Exception {Socket s=new Socket(InetAddress.getLocalHost(), 7000);//输入输出流接收或发送数据InputStream ips = s.getInputStream();OutputStream ops = s.getOutputStream();//字符流按行读取BufferedReader brKey = new BufferedReader(new InputStreamReader(System.in));//得到输出流DataOutputStream dos = new DataOutputStream(ops);//接收服务器端的数据BufferedReader brNet = new BufferedReader(new InputStreamReader(ips));while(true){//按行读取数据  String strWord = brKey.readLine();              dos.writeBytes(strWord + System.getProperty("line.separator"));//写数据加入换行符发送到服务器            //如果输入输入为quit            if("quit".equalsIgnoreCase(strWord)){                  break;              }else{                  System.out.println(brNet.readLine());  //将服务器数据打印输出            }  }dos.close();brNet.close();brKey.close();s.close();}}


0 0
原创粉丝点击