`
xzy_love
  • 浏览: 32841 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

Java中的TCP/UDP网络通信编程

阅读更多

转自http://hi.baidu.com/annleecn/blog/item/269db81d5a5f298d87d6b6d4.html

 

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工具来查看已经被使用的端口

分享到:
评论
1 楼 cuisuqiang 2012-12-25  
Unix 包括Linux和Mac OS X的root用户,非root用户只能邦定1024以上的端口!

相关推荐

    Tcp/udp网络调试助手

    总的来说,“TCP/UDP网络调试助手”是网络开发和调试过程中的得力工具,通过模拟网络通信场景,帮助开发者深入理解TCP和UDP的工作机制,提高网络应用的开发效率和质量。无论是新手还是经验丰富的开发者,都应该熟练...

    TCP/UDP网络聊天室.zip

    【TCP/UDP网络聊天室】项目是一个基于Java Swing开发的网络通信应用,旨在模拟企鹅聊天软件的功能,提供一对一、一对多以及多对多的聊天模式。该项目利用TCP和UDP两种传输层协议来实现不同场景下的数据交换,充分...

    TCP/UDP通信协议编程

    在IT行业中,网络通信是至关重要的一个领域,TCP(传输控制协议)和UDP(用户数据报协议)作为网络层面上的两种主要传输协议,扮演着关键角色。本篇将深入探讨如何使用C语言来实现TCP和UDP通信的客户端与服务器端...

    TCP/UDP模拟服务端

    在IT行业中,网络通信是至关重要的一个领域,TCP(传输控制协议)和UDP(用户数据报协议)是两种最常使用的传输层协议。本项目"TCP/UDP模拟服务端"显然是一个用于学习或实践这两种协议如何工作以及如何构建服务器端...

    TCP/UDP调试助手

    在软件开发中,尤其是在网络编程领域,TCP(传输控制协议)和UDP(用户数据报协议)是两种广泛使用的传输层协议。它们各自具有独特的特性和应用场景,理解并正确运用它们对于优化网络应用的性能至关重要。 TCP是一...

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件、客户端组件和Agent组件

    Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件、客户端组件和Agent组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/C++、C#、Delphi、E(易语言)、Java、Python 等编程语言...

    tcp_udp_socket.zip_Java TCP/UDP_java Tcp _java socket _java tcp

    在IT行业中,网络编程是不可或缺的一部分,特别是在Java开发中,TCP和UDP协议是网络通信的基础。本实验项目“tcp_udp_socket.zip”旨在帮助开发者理解如何使用Java实现TCP和UDP的Socket通信。以下将详细讲解这两个...

    Java+TCP/IP+Socket编程++原书第2版

    在Java中,通过Socket类和ServerSocket类,我们可以实现基于TCP/IP的网络通信。 Java的Socket编程涉及到以下几个关键知识点: 1. **Socket类**:Socket是Java中用于实现TCP通信的类,它代表了客户端到服务器的一个...

    java -> TCP/UDP 连接测试 SocketTest

    在IT行业中,网络通信是软件开发的一个重要领域,TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的网络通信协议。本项目“java -&gt; TCP/UDP 连接测试 SocketTest”专注于通过Java语言实现对这两种协议的连接...

    基于控制台的TCP/UDP协议实现本地文字通信的程序

    从压缩包中的文件名来看,我们可以推测项目的开发可能涉及到了网络通信的实际案例分析、设计模式的应用以及具体的TCP/UDP通信代码实现。"network_fieldship_report_2.odt"和"090834101叶轻舟_network_fieldship_...

    TCP/UDP嗅探器

    TCP(传输控制协议)和UDP(用户数据报协议)是两种广泛使用的网络通信协议,它们各有特点,适用于不同的场景。为了理解和监控网络中的数据流动,嗅探器(Sniffer)应运而生。本篇将深入探讨TCP/UDP嗅探器的工作原理...

    TCP/UDP 传输数据

    总结来说,TCP和UDP是网络通信中不可或缺的协议,它们各有优缺点,选择使用哪种协议取决于应用的需求。理解它们的工作原理和编程实现,对于进行网络编程和优化网络应用至关重要。在实际项目中,开发者应结合TCP和UDP...

    TCP/IP java 编程

    TCP/IP协议是Internet最基本的协议、Internet国际互联网络的基础。定义了电子设备连入因特网的规范。而Socket通信就是基于TCP/IP协议的一直通信机制。...关键字:JAVA SOCKET,TCP/IP,套接字,网络编程

    基于TCP/IP协议的Socket编程

    TCP/IP协议是网络通信协议的基础,它规定了网络上的所有通信设备,尤其是一个主机与另一个主机之间的数据传输格式以及传送方式。TCP/IP协议的基本传输单位是数据包(datagram),TCP协议负责把数据分成若干个...

    java实现TCP+UDP通信

    在IT行业中,网络通信是至关重要的一个领域,Java作为一门广泛应用的编程语言,提供了丰富的API来支持TCP(传输控制协议)和UDP(用户数据报协议)这两种不同的网络通信方式。本篇文章将深入探讨如何使用Java实现TCP...

    JAVA TCP和UDP Socket通信框架

    Java中的TCP和UDP Socket通信是网络编程的基础,用于在不同设备之间建立可靠的数据传输通道。TCP(Transmission Control Protocol)提供的是面向连接、有序且无损的服务,而UDP(User Datagram Protocol)则是无连接...

    java实现的tcpudp通信

    Java 作为一种广泛应用的编程语言,提供了丰富的网络编程接口,使得开发者能够轻松地实现基于 TCP 和 UDP 的通信。本次实验旨在通过实践操作,帮助学生深入理解 TCP 和 UDP 的工作原理,并掌握使用 Java 进行网络...

    Android TCP/UDP Demo

    在Android开发中,TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的网络通信协议,它们各自具有不同的特点和应用场景。本篇将详细讲解Android环境下如何使用TCP和UDP进行通信,并介绍一个名为`TCPUtil`的...

    运用 java 语言 实现 TCP/udp 聊天程序

    Java作为一种多平台支持的语言,提供了丰富的API来实现网络通信,特别是TCP和UDP协议。本教程将深入讲解如何运用Java语言实现TCP和UDP聊天程序。 首先,TCP(Transmission Control Protocol)是一种面向连接的、...

Global site tag (gtag.js) - Google Analytics