江西广告网

标题: 谈谈TCP和UDP的一些简单应用 [打印本页]

作者: 梅子酸酸    时间: 2008-12-27 17:41
标题: 谈谈TCP和UDP的一些简单应用
  网络编程中最重要的就是SOCKET,它其实也就是监听端口的原理。和我们用手机发短信的原理应该是大致无二(我是这样理解的),而JAVA最出色的一点也就是“无痛苦连网”。   网络最基本的精神就是让两台机器连接起来,“被呼叫的一方”也就是服务器,而“找人的一方”则叫做客户机,所以说在连接中服务器、客户机也就是一个相对的概念了。而我们对机器的标识主要是通过IP地址和端口来区分的。   “传输控制协议”TCP和“用户数据报协议”是两种不同的协议,JAVA对这两种协议的支持基本是一致的,而它们本身最大的区别也就是发送的可靠性和速率,前者相比后者是可靠协议,后者当然是速度快得多了,下面我们分别用两个SOCKET下演示:      eg1:      //Clients.java   import java.io.*;   import java.net.*;   public class Clients   {   public static void main(String[] args) throws Exception   {   InetAddress addr = InetAddress.getByName(null);   Socket socket = new Socket(addr,2000);   PrintWriter out =   new PrintWriter(   new BufferedWriter(   new OutputStreamWriter(   socket.getOutputStream())),true);   byte[] b = new byte[2048];   String msg = new String(b,0,System.in.read(b));   out.println(msg);   socket.close();   }   }   //Servers.java   import java.io.*;   import java.net.*;      public class Servers   {   public static void main(String[] args) throws Exception   {   ServerSocket s = new ServerSocket(2000);   try{   while(true){   Socket socket = s.accept();   try{   BufferedReader in =   new BufferedReader(   new InputStreamReader(   socket.getInputStream()));   StringBuffer sb = new StringBuffer();   int c;   while( (c = in.read()) != -1 ){   char ch = (char)c;   sb.append(ch);   }   System.out.println(sb.toString());      }catch(IOException e){   socket.close();   }finally{   socket.close();   }   }//while   }finally{   s.close();   }//try   }//main   }   此程式主要用Servers来进行无限监听,而Clients是客户机发送程式,他们的端口全采用2000。   eg2:      //UDPsend.java   import java.io.*;   import java.net.*;      /**   * This class sends the specified text or file as a datagram to the   * specified port of the specified host.   **/   public class UDPSend {   public static final String usage =   "Usage: java UDPSend ...\n"   " or: java UDPSend -f ";      public static void main(String args[]) {   try {   // Check the number of arguments   if (args.length < 3)   throw new IllegalArgumentException("Wrong number of args");      // Parse the arguments   String host = args[0];   int port = Integer.parseInt(args[1]);      // Figure out the message to send.   // If the third argument is -f, then send the contents of the file   // specified as the fourth argument. Otherwise, concatenate the   // third and all remaining arguments and send that.   byte[] message;   if (args[2].equals("-f")) {   File f = new File(args[3]);   int len = (int)f.length(); // figure out how big the file is   message = new byte[len]; // create a buffer big enough   FileInputStream in = new FileInputStream(f);   int bytes_read = 0, n;   do { // loop until we've read it all   n = in.read(message, bytes_read, len-bytes_read);   bytes_read = n;   } while((bytes_read < len)&& (n != -1));   }   else { // Otherwise, just combine all the remaining arguments.   String msg = args[2];   for (int i = 3; i < args.length; i ) msg = " " args[i];   message = msg.getBytes();   }      // Get the internet address of the specified host   InetAddress address = InetAddress.getByName(host);      // Initialize a datagram packet with data and address   DatagramPacket packet = new DatagramPacket(message, message.length,   address, port);      // Create a datagram socket, send the packet through it, close it.   DatagramSocket dsocket = new DatagramSocket();   dsocket.send(packet);   dsocket.close();   }   catch (Exception e) {   System.err.println(e);   System.err.println(usage);   }   }   }   //UDPreceive.java   import java.io.*;   import java.net.*;      /**   * This program waits to receive datagrams sent the specified port.   * When it receives one, it displays the sending host and prints the   * contents of the datagram as a string. Then it loops and waits again.   **/   public class UDPReceive {   public static final String usage = "Usage: java UDPReceive ";   public static void main(String args[]) {   try {   if (args.length != 1)   throw new IllegalArgumentException("Wrong number of args");      // Get the port from the command line   int port = Integer.parseInt(args[0]);      // Create a socket to listen on the port.   DatagramSocket dsocket = new DatagramSocket(port);      // Create a buffer to read datagrams into. If anyone sends us a   // packet containing more than will fit into this buffer, the   // excess will simply be discarded!   byte[] buffer = new byte[2048];      // Create a packet to receive data into the buffer   DatagramPacket packet = new DatagramPacket(buffer, buffer.length);      // Now loop forever, waiting to receive packets and printing them.   for(;;) {   // Wait to receive a datagram   dsocket.receive(packet);      // Convert the contents to a string, and display them   String msg = new String(buffer, 0, packet.getLength());   System.out.println(packet.getAddress().getHostName()   ": " msg);      // Reset the length of the packet before reusing it.   // Prior to Java 1.1, we'd just create a new packet each time.   packet.setLength(buffer.length);   }   }   catch (Exception e) {   System.err.println(e);   System.err.println(usage);   }   }   }   在UDP中主要的类是DatagramSocket()和DatagramPacket(),而在UDPreceive中,被接受的字节是受限制,这些感觉不是太好,既然buf是一个字节数组,我们实在是很奇怪为什么构建器自己不能调查出数组的长度呢?唯一能猜测的原因就是C风格的编程使然,那里的数组不能自己告诉我们它有多大。   而我们实际使用的过程中,当然不仅仅限于这些,其中要考虑有多台客户机来连接服务器,所以要考虑到线程Thread的使用,如果再加上SWING,就可以做一个类似于QQ的SOCKET功能了,这仅仅限于我在学习SOCKET时的一些领悟。供大家参考。   




欢迎光临 江西广告网 (http://bbs.jxadw.com/) Powered by Discuz! X3.2