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是.ServerSocket(用于服务器端)和.Socket(用于客户端);UDP是.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 .DatagramPacket;

  import .DatagramSocket;

  import .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 .DatagramPacket;

  import .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网络服务程序,首先要用到.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 .ServerSocket;

  import .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 .ServerSocket;

  import .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 .ServerSocket;

  import .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 .InetAddress;

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

Java中的TCP/UDP网络通信编程的更多相关文章

  1. Java TCP/UDP网络通信编程

    本文转自:http://www.cnblogs.com/cdtarena/archive/2013/04/10/3012282.html 网络应用中基本上都是TCP(Transmission Cont ...

  2. 三十天学不会TCP,UDP/IP编程--MAC地址和数据链路层

    这篇文章主要是来做(da)推(guang)介(gao)的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,后面会 ...

  3. java多线程实现TCP网络Socket编程(C/S通信)

    目录 开篇必知必会 一.多线程技术 二.实现多线程接收 1.单线程版本 2.多线程版本 三.多线程与进程的关系 四.客户端界面完整代码 五.多线程通信对比 最后 开篇必知必会 在前一篇<Java ...

  4. Java 中的 IO 与 socket 编程 [ 复习 ]

    一.Unix IO 与 IPC Unix IO:Open-Read or Write-Close IPC:open socket - receive and send to socket - clos ...

  5. TCP UDP基本编程(一)

    tcp udp均可以用来网络通信,在使用之前建议先搜索一下相关网络连接的基本知识,可以更好的理解和使用,tcp建议看下如下文章:https://blog.csdn.net/chuangsun/arti ...

  6. 异常处理与网络基础中的tcp,udp协议

    # 异常处理: # 什么是异常?异常和错误的区别 # Error 语法错误 比较明显的错误 在编译代码阶段就能检测出来 # Iteration 异常 在执行代码的过程中引发的异常 # 异常发生之后的效 ...

  7. Java中基于HTTP协议网络编程

    java中为我们的网络支持提供了java.net包,能够使我们以编程的方式来訪问Web服务功能,这篇博客,就跟大家分享一下.Java中的网络编程的知识.主要是学习下该java.net包下的API. U ...

  8. java scoket http TCP udp

    http://blog.csdn.net/kongxx/article/details/7259436 TCP/UDP: 齐全:http://www.blogjava.net/Reg/archive/ ...

  9. 网络编程基础socket 重要中:TCP/UDP/七层协议

    计算机网络的发展及基础网络概念 问题:网络到底是什么?计算机之间是如何通信的? 早期 : 联机 以太网 : 局域网与交换机 广播 主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无 ...

随机推荐

  1. FindWindowEx

    procedure CloseGameSver(); var H1, h2: HWND; begin H1 := FindWindow('TForm1', nil); h2 := FindWindow ...

  2. Redis学习手册(实例代码)

    在之前的博客中已经非常详细的介绍了Redis的各种操作命令.运行机制和服务器初始化参数配置.本篇博客是该系列博客中的最后一篇,在这里将给出基于Redis客户端组件访问并操作Redis服务器的代码示例. ...

  3. JavaScript引擎的工作原理

    http://my.oschina.net/fuckBAT/blog/318355?fromerr=jK6wCh1p#OSC_h4_4

  4. 我们应该如何去了解JavaScript引擎的工作原理 系列

    http://www.nowamagic.net/librarys/veda/detail/1579

  5. careercup-递归和动态规划 9.4

    9.4 编写一个方法,返回某集合的所有子集. 类似leetcode:Subsets 解法: 解决这个问题之前,我们先要对时间和空间复杂度有个合理的评估.一个集合会有多少子集?我们可以这么计算,生成了一 ...

  6. oracle表锁住 解锁办法

    第一种方法: 用系统账户如sys      as  SYSDBA 登录进去 1.查看数据库锁,诊断锁的来源及类型:  select object_id,session_id,locked_mode f ...

  7. dependencies与devDependencies的区别

    npm install在安装node模块时,有两种命令参数可以把它们的信息写入package.json文件: –save –save-dev 但它的文档里1,只提到一个小区别,–save会把依赖包名称 ...

  8. ffmpeg之YUYV转RGB ARM使用流程分析

    本例基于3.2.2 ffmpeg 一.应用调用API 二.头文件包含的API接口 对应于libswscale.so.libswscale.so.4.libswscale.so.4.2.100中 sws ...

  9. 20160501--struts2入门3

    一.自定义拦截器 要自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口: public class PermissionInterc ...

  10. TCP调试助手

    网络开发经常要用到一些TCP&UDP的调试工具,搜集一些备用. 目前总结工具有(不分先后): chrome等自带调试器调试HTTP Fiddler(.NET)和Charles debugger ...