您的位置:首页 > 理论基础 > 计算机网络

java网络编程

2014-03-17 00:07 288 查看
UDP:

a)        将数据及源和目的封装成数据包中,不需要建立连接

b)        每个数据报的大小限制在64K内

c)        因无连接,是不可靠协议

d)        不需要建立连接,速度快

TCP:

a)        建立连接,形成传输数据的通道

b)        在连接中进行大数据传输

c)        通过三次握手完成连接,是可靠协议



应用:
1,TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高
2,UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。
基于Socket的java网络编程

a)        就是为网络服务提供的一种机制

b)        通信的两端都有Socket

c)        网络通信其实就是socket间的通信

d)        数据在2个Socket间通过IO传输

 
1,什么是Socket
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。
但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
2,Socket通讯的过程
Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
  (1) 创建Socket;
  (2) 打开连接到Socket的输入/出流;
  (3) 按照一定的协议对Socket进行读/写操作;
  (4) 关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)
3,创建Socket
创建Socket
java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下:
  Socket(InetAddress address, int port);
  Socket(InetAddress address, int port, boolean stream);
  Socket(String host, int prot);
  Socket(String host, int prot, boolean stream);
  Socket(SocketImpl impl)
  Socket(String host, int port, InetAddress localAddr,int localPort)
  Socket(InetAddress address, int port, InetAddresslocalAddr, int localPort)
  ServerSocket(int port);
  ServerSocket(int port, int backlog);
  ServerSocket(int port, int backlog, InetAddressbindAddr)
  其中address、host和port分别是双向连接中另一方的IP地址、主机名和端口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和 bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可 以用来创建Socket。count则表示服务端所能支持的最大连接数。
  Socket client = new Socket("127.0.01.", 80);
  ServerSocket server = new ServerSocket(80);
  注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才 能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。端口范围:0-65535,其中0~1024系统使用或保留端口
  在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。
4,支持多客户的client/server程序
前面的Client/Server程序只能实现Server和一个客户的对话。在实际应用 中,往往是在服务器上运行一个永久的程序,它可以接收来自其他多个客户端的请求,提供相应的服务。为了实现在服务器方给多个客户提供服务的功能,需要对上 面的程序进行改造,利用多线程实现多客户机制。服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,服务器就会启动一个专门的服务线程来响 应该客户的请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。
5,简单的Client/Server程序
获得指定url的ip地址及名字
package com.wj.ip;
 
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
 * 得到ip地址
 * @author wJing
 * time:2014/2/9
 */
public class IPDemo1 {
   /**
    *
    * @param args
    * @throws Exception
    */
   public staticvoid main(String[] args) throws Exception {
       InetAddress i= InetAddress.getLocalHost();
       System.out.println(i.toString());
       System.out.println(i.getHostName());
       System.out.println(i.getHostAddress());
      
       InetAddressia = InetAddress.getByName("127.0.0.1");
       System.out.println("address:"+ia.getHostAddress());
       System.out.println("ip:"+ ia.getHostName());
   }
}
简单的Client(发送文本):
package com.wj.client;
 
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileReader;
import java.io.IOException;
imp
4000
ort java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
 
/**
 *
 * @author wJing
 * time:2014-2-915:09:54
 * 把客户端的一个文件传递到服务端,模拟
 */
public class TextClient {
 
   public staticvoid main(String[] args) throws Exception, IOException {
       Socket s =new Socket("localhost", 9999);
      
       BufferedReaderbuf = new BufferedReader(new FileReader("d:\\abcde.txt"));
      
       PrintWriterwriter = new PrintWriter(s.getOutputStream(),true);
      
       /*
       /////////////////////////////////////////////////////////////////
       //时间戳,确定文件的结束标记
       DataOutputStreamdos = new DataOutputStream(s.getOutputStream());
       long time =System.currentTimeMillis();
       dos.writeLong(time);
      
       ////////////////////////////////////////////////////////////////
      
       */
      
      
       String line =null;
      
       while((line =buf.readLine()) != null) {
          writer.println(line);
       }
       //关闭客户端输出流
      
       s.shutdownOutput();
      
      
       ////////////////////////////////////////////////////////
//     writer.println(time);//文件读完以后再发一次时间戳
       ///////////////////////////////////////////////////////////
       BufferedReaderin = new BufferedReader(new InputStreamReader(s.getInputStream()));
       String str =in.readLine();
       System.out.println(str);
      
       buf.close();
       s.close();
   }
 
}
简单的Server(接收文本):
package com.wj.server;
 
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
 
public class TextServer {
 
   public staticvoid main(String[] args) throws Exception {
       ServerSocketss = new ServerSocket(9999);
       Socket s =ss.accept();
      
       BufferedReaderbufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
      
       PrintWriterin = new PrintWriter(new FileWriter("e://copy.txt"),true);
      
       /**
        *
       ///////////////////////////////////////////////////////////
       DataInputStreamdis = new DataInputStream(s.getInputStream());
       long time =dis.readLong();
       ///////////////////////////////////////////////////////////
      
       /**
        * 方式1:发送一个标记给服务器
        * 方式2:使用时间戳当作一个标记
        * 方式3:使用socket的shutdowninput、shutdownoutput
        */
      
      
       String line =null;
       while((line =bufIn.readLine()) != null) {
//        if(line.equals(time)){
//            break;
//        }
          in.println(line);
       }
      
       PrintWriterout = new PrintWriter(s.getOutputStream(), true);
       out.println("上传成功");
      
       in.close();
       s.close();
       ss.close();
   }
 
}
简单的Client(发送图片):
package com.wj.client;
 
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
 
/**
 *
 * @author wJing
 * time:2014-2-916:38:57
 * 上次图片
 */
public class ImageClient {
 
   public staticvoid main(String[] args) throws Exception, IOException {
       Socket s =new Socket("localhost", 1520);
       FileInputStreamfis = new FileInputStream("d:\\1.jpg");
      
       OutputStreamout = s.getOutputStream();
      
       byte[] buf =new byte[1024];
      
       int len = 0;
      
       while((len =fis.read(buf)) != -1) {
          out.write(buf,0, len);
       }
      
       //告诉服务器数据已写完
       s.shutdownOutput();
      
       InputStreamin = s.getInputStream();
       byte[] bufIn= new byte[1024];
       int num =in.read(bufIn);
      
       System.out.println(newString(bufIn, 0, num));
      
       fis.close();
       s.close();
   }
 
}
简单的Server(接收图片)
package com.wj.server;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
 
class picThread implements Runnable {
   private Socket s;
   publicpicThread(Socket s) {
       this.s = s;
   }
   @Override
   public void run(){
       int count =1;
       String ip =s.getInetAddress().getAddress().toString();
       System.out.println(ip+ ".....connected");
       try {
       InputStreamin = s.getInputStream();
      
       File file =new File(ip+count + ".jpg");
       while(file.exists()){
          file = newFile(ip + "(" + count++ + ").jpg");
       }
 
       FileOutputStreamfos = new FileOutputStream(file);
 
       byte[] buf =new byte[1024];
       int len = 0;
       while((len =in.read(buf)) != -1) {
          fos.write(buf,0, len);
       }
 
       OutputStreamout = s.getOutputStream();
       out.write("上次成功".getBytes());
 
       fos.close();
       s.close();
       }catch(Exception e) {
          throw newRuntimeException(ip + "上传失败");
       }
   }
 
}
 
public class ImageServer {
   public staticvoid main(String[] args) throws Exception {
       //  UploadPic();
 
 
       //使用多线程处理多个客户端的访问
       ServerSocketss = new ServerSocket(1520);
       while(true) {
          Socket s =ss.accept();
          newThread(new picThread(s)).start();
       }
   }
 
 
   //先线程的图片上传,一个客户端连上以后只有等为他服务完成以后才能为下一个人服务
   private staticvoid UploadPic() throws IOException, FileNotFoundException {
       ServerSocketss = new ServerSocket(1520);
       //     while(true) {
       Socket s =ss.accept();
 
       InputStreamin = s.getInputStream();
 
       FileOutputStreamfos = new FileOutputStream("e:\\server.jpg");
 
       byte[] buf =new byte[1024];
       int len = 0;
       while((len =in.read(buf)) != -1) {
          fos.write(buf,0, len);
       }
 
       OutputStreamout = s.getOutputStream();
       out.write("上次成功".getBytes());
 
       fos.close();
       s.close();
       //     }
       ss.close();
   }
}
 
 
 
 
 
一个基于UDP的简单聊天程序:
package com.wj.udp;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
 
/**
 *
 * @author wJing
 *编写一个聊天程序
 *time:2014-2-9 11:33:20
 */
 
class Send implements Runnable {
   privateDatagramSocket ds;
  
   publicSend(DatagramSocket ds) {
       this.ds = ds;
   }
  
   @Override
   public void run(){
      
       try {
          BufferedReaderin = new BufferedReader(new InputStreamReader(System.in));
          Stringline = null;
          while((line= in.readLine()) != null) {
              if("886".equals(line)){
                 break;
              }
              byte[] buf = line.getBytes();
              DatagramPacketdp = new DatagramPacket(buf, buf.length,InetAddress.getByName("localhost"), 10002);
              ds.send(dp);
          }
       } catch(Exception e) {
          throw newRuntimeException("发送端失败");
       }
   }
  
}
 
class Receive implements Runnable {
   private DatagramSocketds;
  
   publicReceive(DatagramSocket ds) {
       this.ds = ds;
   }
   @Override
   public void run(){
       try {
          while(true){
              byte[]buf = new byte[1024 * 64];
              DatagramPacketdp = new DatagramPacket(buf, buf.length);
              ds.receive(dp);
             
              Stringip = dp.getAddress().getHostAddress();
              Stringdata = new String(dp.getData(), 0, dp.getLength());
              System.out.println("ip->"+ ip + ":" + data);
          }
       } catch(Exception e) {
          throw newRuntimeException("接收失败");
       }
   }
  
}
 
public class ChatDemo {
 
   public staticvoid main(String[] args) throws Exception {
       DatagramSocketsendSocket = new DatagramSocket();
       DatagramSocketreceiveSocket = new DatagramSocket(10002);
      
       newThread(new Send(sendSocket)).run();
       newThread(new Receive(receiveSocket)).run();
   }
 
}

96b3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java socket