udp与tcp编程区别

来源:互联网 发布:淘宝自动点内容回复 编辑:程序博客网 时间:2024/05/17 02:22

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

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

网络应用中基本上都是TCP(Transmission Control Protocol传输控制协议)和UDP(User Datagram Protocol用户数据报协议),TCP是面向连接的通信协议,UDP是无连接的通信协议.

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

1,Java编写UDP网络程序

1.1,DatagramSocket

DatagramSocket有如下构造方法:
1,DatagramSocket() :构造数据报套接字并将其绑定到本地主机上任何可用的端口。
2,DatagramSocket(int port):创建数据报套接字并将其绑定到本地主机上的指定端口。
3,DatagramSocket(int port, InetAddress laddr):创建数据报套接字,将其绑定到指定的本地地址。即指定网卡发送和接收数据.

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

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

发送数据使用DatagramSocket.send(DatagramPacket p)方法,接收数据使用DatagramSocket.receive(DatagramPacket p)方法.

1.2,DatagramPacket

DatagramPacket类有如下构造方法:
1,DatagramPacket(byte[] buf, int length):构造 DatagramPacket,用来接收长度为length的数据包。
2,DatagramPacket(byte[] buf, int length, InetAddress address, int port):构造数据报包,用来将长度为length的包发送到指定主机上的指定端口号。

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

1.3,InetAddress

Java中对IP地址进行包装的类,

DatagramPacket.getAddress()可以获取发送或接收方的IP地址.DatagramPacket.getPort()可以获取发送或接收方的端口.

1.4,UDP程序例子

发送程序:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UdpSend {

public static void main(String[] args) throws Exception {
   DatagramSocket ds = new DatagramSocket();
   String str = "hello , world!";
   DatagramPacket dp = new DatagramPacket(str.getBytes(),str.length(),InetAddress.getByName("192.168.0.105"),3000);
   ds.send(dp);
   ds.close(); //关闭连接
}
}

接收程序:
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UdpRecv {
public static void main(String[] args) throws Exception {
   DatagramSocket ds = new DatagramSocket(3000);
   byte[] buf = new byte[1024];
   DatagramPacket dp = new DatagramPacket(buf,buf.length);
   ds.receive(dp);
   String str = new String(dp.getData(),0,dp.getLength());
   System.out.println(str);
   System.out.println("IP:" + dp.getAddress().getHostAddress() + ",PORT:" + dp.getPort());
   ds.close();
}
}
测试要先运行接收程序,再运行发送程序.如果接收程序没有接收到数据,则会一直阻塞,接收到数据后才会关闭程序.如果网络上没有数据发送过来,接收程序也没有阻塞,通常都是使用了一个已经被占用的端口.

2,Java编写TCP网络程序

2.1,ServerSocket

编写TCP网络服务程序,首先要用到java.net.ServerSocket类用以创建服务器Socket.它的常用构造方法有:
1,ServerSocket(int port):创建绑定到特定端口的服务器套接字。
2,ServerSocket(int port, int backlog):利用指定的backlog(服务器忙时保持连接请求的等待客户数量),创建服务器套接字并将其绑定到指定的本地端口号。
3,ServerSocket(int port, int backlog, InetAddress bindAddr):使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。

2.2,Socket

客户端要与服务器建立连接,必须先创建一个Socket对象,它的常用构造方法有:
1,Socket(String host, int port):创建一个流套接字并将其连接到指定主机上的指定端口号。
2,Socket(InetAddress address, int port):创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
3,Socket(InetAddress address, int port, InetAddress localAddr, int localPort):创建一个套接字并将其连接到指定远程端口上的指定远程地址。
4,Socket(String host, int port, InetAddress localAddr, int localPort):创建一个套接字并将其连接到指定远程主机上的指定远程端口。

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

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

2.3,TCP程序例子的服务器程序:

import java.io.InputStream;
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(8000);
   Socket s = ss.accept();
   InputStream ips = s.getInputStream();
   OutputStream ops = s.getOutputStream();
   ops.write("hello,World!".getBytes());
   byte[] buf = new byte[1024];
   int len = ips.read(buf);
   System.out.println(new String(buf,0,len));
   ips.close();
   ops.close();
   s.close();
   ss.close();
}
}
在这个程序里,创建了一个在8000端口上等待连接的ServerSocket对象,当接收到一个客户的连接请求后,程序从与这个客户建立了连接的Socket对象中获得输入输出流对象,通过输出流首先向客户端发送一串字符,然后通过输入流读取客户端发送过来的信息,并将这些信息打印,然后关闭所有资源.

要先运行服务器程序,然后才能运行客户端程序,当TCP服务器程序运行到Socket.accpet()方法等待客户连接时,accept方法将阻塞,一直到有客户连接请求到来,该方法才会返回,如果又没有请求到来,又没有发生阻塞,通常都是使用了一个已经被占用的端口.

我们可以使用windows提供的telnet工具在命令行窗口中测试一下服务器程序:命令如下:telnet localhost 8000

可以看到,telnet只要有输入就发送,因此我们如果想要在服务器端一次读多个字符的话,还需要进一步处理,看如下代码:
import java.io.BufferedReader;
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(8000);
   Socket s = ss.accept();
   InputStream ips = s.getInputStream();
   BufferedReader br = new BufferedReader(new InputStreamReader(ips)); //对InputStream进行包装,增加了缓存
   OutputStream ops = s.getOutputStream();
   ops.write("hello,World!".getBytes());
   System.out.println(br.readLine());
   br.close(); //关闭包装类,会自动关闭里面的基类
   ops.close();
   s.close();
   ss.close();
}
}

再次使用telnet工具可以看到,这次可以发送不止一个字符了,按回车键后发送数据到服务器端.

2.4,TCP程序例子改进后的服务器程序:

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

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

下面是一个例子,客户端向服务器发送一个字符串,服务器将这个字符串中的所有字符反向排列后回送给客户端.客户端输入"quit",退出程序.
import java.io.BufferedReader;
import java.io.DataOutputStream;
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(8000);
   while(true){
    Socket s = ss.accept();
    new Thread(new Servicer(s)).start();
   }
}
}

class Servicer implements Runnable{
Socket s;
public Servicer(Socket s){
   this.s = s;
}
public void run(){
   try{
    InputStream ips = s.getInputStream();
    OutputStream ops = s.getOutputStream();
   
    BufferedReader br = new BufferedReader(new InputStreamReader(ips));
    DataOutputStream dos = new DataOutputStream(ops);
    while(true){
     String strWord = br.readLine();
     if(strWord.equalsIgnoreCase("quit")){
      break;
     }
     String strEcho = (new StringBuffer(strWord).reverse().toString());
     dos.writeBytes(strWord + "------->" + strEcho + System.getProperty("line.separator"));
    }
    br.close();
    dos.close();
    s.close();
   }catch(Exception e){
    e.printStackTrace();
   }
}
}

2.5,TCP程序例子客户端程序:


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{
   if(args.length < 2){
    System.out.println("Usage:java TcpClient ServerIP ServerPort");
    return ;
   }
   Socket s = new Socket(InetAddress.getByName(args[0]),Integer.parseInt(args[1]));
   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"));
    if("quit".equalsIgnoreCase(strWord)){
     break;
    }else{
     System.out.println(brNet.readLine());
    }
   }
   dos.close();
   brNet.close();
   brKey.close();
   s.close();
}
}
先运行服务器程序,再在命令行使用java TcpClient 192.168.0.3 8000,这样就启动了客户端程序.我们可以启动多个客户端程序.

我们可以利用netstat工具来查看已经被使用的端口http://hi.baidu.com/annleecn/blog

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 断奶后乳房有硬块怎么办 断奶了有硬块疼怎么办 断奶时乳房有硬块怎么办 憋奶乳房有硬块怎么办 回奶以后有硬块怎么办 回奶里面有肿块怎么办 回奶时候的硬块怎么办 回奶乳房有硬块怎么办 回奶胀痛有硬块怎么办 回奶期间有硬块怎么办 回奶期间乳房有硬块怎么办 回奶乳房有肿块怎么办 牛犊子出生3天喘怎么办 猪高烧不退不吃怎么办 苹果6刷机失败怎么办 uc能看不能下怎么办 苹果6s铃声太小怎么办 苹果6铃声声音小怎么办 苹果7来电铃声小怎么办 红米手机声音小怎么办 微信安装不上去怎么办 6s无法安装微信怎么办 苹果4微信版本低怎么办 新手机没有微信怎么办 新手机登陆微信怎么办 新号码被注册过怎么办 微信注册不了怎么办啊 苹果4铃声不响怎么办 苹果6黑屏没反应怎么办 苹果7卡机黑屏了怎么办 苹果7手机铃声小怎么办 支付宝发现套现怎么办 空调滴水管断了怎么办 地漏下水管断了怎么办 脸上长白色糠疹怎么办 腋下长白色的毛怎么办 饥荒电羊死光了怎么办 6s储存空间虚满怎么办 大胸下垂穿婚纱怎么办 美团签约成功后怎么办 拍婚纱照笑不出来怎么办