Java:网络编程

一、Socket(套接字)

  连接原理:

  

1、Socket客户端:

  Socket s=new Socket(ip,port);打开一个套接字,它是网络编程中的一个抽象概念,负责启动该程序内部和外部之间的通信。如果连接失败,将会抛出一个UnknownHostException异常;如果存才其他问题,将会抛出IOException异常。

  InputStream inStream=s.getInputStream();用于接收数据。
  OutputStream outStream=s.getOutputStream();用于发送数据。

2、套接字超时

  有两种超时情况:

    1):从套接字读取信息时,在有数据可供访问之前,读操作将会被堵塞。如类似in.nextLine();

      解决办法:调用setSoTimeout方法设置一个超时值。即调用s.setSoTimeout(1000);

    2):Socket(String host,int port)会一直堵塞,直到建立了到达机主的初始连接为止。(实例化Socket时会堵塞)

      解决办法:先构建一个无连接的套接字,然后再使用一个超时来进行连接的方法。即s.connect(new InetSocketAddress(host,port),timeout);

3、Socket服务器:

  它可以向客户端发送消息,一旦启动服务器程序,它便等待某个客户端连接到它的端口。ServerSocket用于建立套接字。

  ServerSocket s=new ServerSocket(port);创建一个端口
  Socket incoming=s.accept();告诉服务器不停等待,直到有客户端连接到这个端口,该方法会返回一个Socket对象,用这个对象得到输入、输出流。
  InputStream inStream=incoming.getInputStream();接收数据
  OutputStream outStream=incoming.getOutputStream();发送数据

  如果通过套接字发送文本,可以将流转换成扫描器和写入器。

    Scanner in=new Scanner(inStream);
  PrintWriter out=new PrintWriter(outStream,true);
  System.out.println("hello....");向客户端发送消息    

  最后要关闭连接进来的套接字。

     incoming.close();关闭套接字 

 一个简单的服务器向客户端发送数据报的例子1:

 1 package socket;
 2 import java.net.*;
 3 public class server {
 4     public static void main(String[] args)throws Exception{
 5         DatagramSocket server=new DatagramSocket(3000);
 6         String str="hello";
 7         DatagramPacket packet=new DatagramPacket(str.getBytes(),str.length(),InetAddress.getLocalHost(),9000);
 8         server.send(packet);
 9         server.close();
10     }
11 }
package socket;
import java.net.*;
import java.io.*;
public class client {
    public static void main(String[] args)throws IOException{
        byte[] buf=new byte[1024];
        DatagramPacket packet=new DatagramPacket(buf,1024);
        DatagramSocket client=new DatagramSocket(9000);
        client.receive(packet);
        String str=new String(buf,0,packet.getLength());
        System.out.println(packet.getAddress().getHostName()+":"+str);
        client.close();
    }
}

结果为:Feng:hello

例子2:简单的聊天设计

  服务器端:

 1 package socket;
 2
 3
 4 import java.awt.BorderLayout;
 5 import java.awt.event.ActionEvent;
 6 import java.awt.event.ActionListener;
 7 import java.io.BufferedReader;
 8 import java.io.InputStreamReader;
 9 import java.io.PrintStream;
10 import java.net.InetAddress;
11 import java.net.ServerSocket;
12 import java.net.Socket;
13
14 import javax.swing.JButton;
15 import javax.swing.JFrame;
16 import javax.swing.JPanel;
17 import javax.swing.JScrollPane;
18 import javax.swing.JTextArea;
19 import javax.swing.JTextField;
20
21 @SuppressWarnings("serial")
22 public class Server3 extends JFrame{
23     static JTextArea area;
24     JTextField field;
25     JButton button;
26     static PrintStream writer;
27     public Server3(){
28         this.setTitle("服务器");
29         this.setSize(400,500);
30         area = new JTextArea(25,30);
31         area.setEditable(false);
32         field = new JTextField(20);
33         button = new JButton("提交");
34         JPanel panel = new JPanel();
35         JScrollPane sp = new JScrollPane(area);
36         this.add(sp,BorderLayout.CENTER);
37         panel.add(field);
38         panel.add(button);
39         this.add(panel,BorderLayout.SOUTH);
40         this.setVisible(true);
41         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
42
43         button.addActionListener(new ActionListener(){
44
45             @Override
46             public void actionPerformed(ActionEvent e) {
47                 String text = field.getText();
48                 writer.println(text);
49                 area.append("我:"+text+"\n");
50                 field.setText("");
51             }
52         });
53     }
54     public static void main(String[] args) throws Exception {
55         Server3 s = new Server3();
56         ServerSocket server = new ServerSocket(8899);
57         System.out.println("开始监听...");
58         Socket socket = server.accept();
59         InetAddress address = socket.getInetAddress();
60         String name = address.getLocalHost().getHostName();
61         System.out.println(name+"已连接");
62         BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
63         writer = new PrintStream(socket.getOutputStream(), true);
64         while (true) {
65             String line = null;
66             line = reader.readLine();
67             if (line != null) {
68                     area.append("客户端:"+line+"\n");
69             }
70
71         }
72     }
73
74 }

  客户端:

 1 package socket;
 2 import java.awt.BorderLayout;
 3 import java.awt.event.ActionEvent;
 4 import java.awt.event.ActionListener;
 5 import java.io.BufferedReader;
 6 import java.io.InputStreamReader;
 7 import java.io.OutputStream;
 8 import java.io.PrintStream;
 9 import java.io.PrintWriter;
10 import java.net.Socket;
11
12 import javax.swing.JButton;
13 import javax.swing.JFrame;
14 import javax.swing.JPanel;
15 import javax.swing.JScrollPane;
16 import javax.swing.JTextArea;
17 import javax.swing.JTextField;
18
19 public class Client3 extends JFrame{
20
21     static JTextArea area;
22     JTextField field;
23     JButton button;
24     static PrintWriter writer;
25     public Client3(){
26         this.setTitle("客户端");
27         this.setSize(400,500);
28         area = new JTextArea(25,30);
29         area.setEditable(false);
30         field = new JTextField(20);
31         button = new JButton("提交");
32         JScrollPane sp = new JScrollPane(area);
33         JPanel panel = new JPanel();
34         this.add(sp,BorderLayout.CENTER);
35         panel.add(field);
36         panel.add(button);
37         this.add(panel,BorderLayout.SOUTH);
38         this.setVisible(true);
39         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
40
41         button.addActionListener(new ActionListener(){
42
43             @Override
44             public void actionPerformed(ActionEvent e) {
45                 String text = field.getText();
46                 writer.println(text);
47                 area.append("我:"+text+"\n");
48                 field.setText("");
49             }
50
51         });
52     }
53     public static void main(String[] args) throws Exception{
54         Client3 c = new Client3();
55         Socket socket = new Socket("127.0.0.1",8899);
56         OutputStream out = socket.getOutputStream();
57         BufferedReader reader1 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
58         writer = new PrintWriter(out,true);
59         System.out.println("已经成功和服务器连接...");
60         while(true){
61             String line = reader1.readLine();
62             area.append("服务器:"+line+"\n");
63         }
64     }
65
66 }

4、为多个客户端服务

  当多个客户端连接到服务器时,要用到线程机制。每当程序建立一个新的套接字连接,也就是当调用accept时,将启动一个新的线程来处理服务器和该客户端之间的连接(一个服务器一个线程),而主程序将返回并等待下一个连接。即执行如下命令:

        while(true){
      Socket incoming=s.accpet();
      Runnable r=new  ThreadEchoHandler(incoming);   
 
      Thread t=new Thread(r);
      t.start();
    }    

例子:

 1 package socket;
 2 import java.net.*;
 3 import java.io.*;
 4 import java.util.*;
 5 public class server1 {
 6     public static void main(String[] args)throws Exception{
 7         try{int i=1;
 8             ServerSocket s=new ServerSocket(9000);
 9             while(true){
10                 Socket incoming=s.accept();
11                 PrintWriter out=new PrintWriter(incoming.getOutputStream(),true);
12                 Runnable r=new ThreadedEchoHandler(incoming);
13                 Thread t=new Thread(r);
14                 t.start();
15                 i++;
16                 Scanner in=new Scanner(System.in);
17                 while(in.hasNextLine()){
18                     System.out.println(in.nextLine());
19                 }
20             }
21         }catch(Exception e){e.printStackTrace();}
22     }
23 }
24 class ThreadedEchoHandler implements Runnable{
25     private Socket s;
26     public ThreadedEchoHandler(Socket i){
27         s=i;
28     }
29     public void run(){
30         try{
31             try{
32                 Scanner in=new Scanner(s.getInputStream());
33                 String str=null;
34                 while(true){
35                     str=in.nextLine();
36                     System.out.println("客户端说:"+str);
37                 }
38             }
39             finally{s.close();}
40         }
41         catch(Exception e){e.printStackTrace();}
42     }
43 }

 1 package socket;
 2 import java.net.*;
 3 import java.io.*;
 4 import java.util.*;
 5 public class clent1 {
 6     public static void main(String[] args)throws Exception{
 7         try{int i=1;Socket s=new Socket("localhost",9000);
 8             while(true){
 9                 PrintWriter out=new PrintWriter(s.getOutputStream(),true);
10                 Runnable r=new ThreadedEchoHandler1(s);
11                 Thread t=new Thread(r);
12                 t.start();
13                 i++;
14                 Scanner in=new Scanner(System.in);
15                 while(in.hasNextLine()){
16                     System.out.println(in.nextLine());
17                 }
18             }
19         }catch(Exception e){e.printStackTrace();}
20     }
21 }
22 class ThreadedEchoHandler1 implements Runnable{
23     private Socket s;
24     public ThreadedEchoHandler1(Socket i){
25         s=i;
26     }
27     public void run(){
28         try{
29             try{
30                 Scanner in=new Scanner(s.getInputStream());
31                 String str=null;
32                 while(true){
33                     str=in.nextLine();
34                     System.out.println("客户端"+s+"说:"+str);
35                 }
36             }
37             finally{s.close();}
38         }
39         catch(Exception e){e.printStackTrace();}
40     }
41 }

5、半关闭

  当我们在向服务器发送数据时,但并不知道要传输多少数据。在向文件写数据时,我们需要在写入后关闭文件即可。但是,如果关闭了一个套接字,那么与服务器就立刻断开了,因而无法读取服务器响应了。用半关闭的方法解决上述问题。可以通过关闭一个套接字的输出流来表示发送给服务器的请求数据已经结束,但是必须保持输入流处于打开状态。

socket.shutdownOutput();关闭输出流。

  例如:客户端发送hello给服务器后,关闭输出流,服务器收到后,关闭输入流,等待5秒后,向客户端发送ECHO hello。

    

时间: 2024-11-08 17:12:22

Java:网络编程的相关文章

用java网络编程中的TCP方式上传文本文件及出现的小问题

自己今天刚学java网络编程中的TCP传输,要用TCP传输文件时,自己也是遇到了一些问题,抽空把它整理了一下,供自己以后参考使用. 首先在这个程序中,我用一个客户端,一个服务端,从客户端上传一个文本文件给服务端,服务端接收数据并显示“上传成功”给客户端. 客户端: 1 import java.io.BufferedReader; 2 import java.io.FileReader; 3 import java.io.IOException; 4 import java.io.InputStr

Java网络编程基础(六)— 基于TCP的NIO简单聊天系统

在Java网络编程基础(四)中提到了基于Socket的TCP/IP简单聊天系统实现了一个多客户端之间护法消息的简单聊天系统.其服务端采用了多线程来处理多个客户端的消息发送,并转发给目的用户.但是由于它是基于Socket的,因此是阻塞的. 本节我们将通过SocketChannel和ServerSocketChannel来实现同样的功能. 1.客户端输入消息的格式 username:msg    username表示要发送的的用户名,msg为发送内容,以冒号分割 2.实现思路 实现思路与Java网络

java网络编程serversocket

转载:http://www.blogjava.net/landon/archive/2013/07/24/401911.html Java网络编程精解笔记3:ServerSocket详解ServerSocket用法详解 1.C/S模式中,Server需要创建特定端口的ServerSocket.->其负责接收client连接请求. 2.线程池->包括一个工作队列和若干工作线程->工作线程不断的从工作队列中取出任务并执行.-->java.util.concurrent->线程池

20145311实验四 "Java网络编程及安全"

20145311实验四 "Java网络编程及安全" 程序设计过程 实验内容 ·掌握Socket程序的编写:·掌握密码技术的使用:·设计安全传输系统 ·利用加解密代码包,编译运行代码,一人加密,一人解密:·集成代码,一人加密后通过TCP发送: 实验步骤 在这之前进行了一个socket连接的例子:用百度做了个实验 下面是两人合作进行RSA的加密: 首先建立一个Socket对象,用来连接特定服务器的指定端口(我负责的是服务器端,郑凯杰负责的是客户端,所以也就是输入我这边的ip地址),输入的参

java网络编程socket解析

转载:http://www.blogjava.net/landon/archive/2013/07/02/401137.html Java网络编程精解笔记2:Socket详解 Socket用法详解 在C/S通信模式中,client需要主动创建于server连接的Socket(套接字).服务器端收到了客户端的连接请求,也会创建与客户连接的Socket.Socket可看做是通信两端的收发器.server与client都通过Socket来收发数据. 1.构造Socket 1.Socket() 2.So

20145331实验五 Java网络编程及安全

实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统 4.结队伙伴:20145333赵嘉鑫 博客地址:http://home.cnblogs.com/u/5301z/ 5.分工:自己负责服务端,伙伴负责客户端 实验要求 1.基于Java Socket实现安全传输 2.基于TCP实现客户端和服务器,结对编程一人负责客户端,一人负责服务器 3.使用Git进行版本控制 4.选择对称算法进行数据加解密. 5.选择非对称算法对对称加密密

20145301实验五 Java网络编程及安全

北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.05.06 18:30-21:30 实验名称:实验五 Java网络编程 实验内容 1.用书上的TCP代码,实现服务器与客户端. 2.客户端与服务器连接 3.客户端中输入明文,利用DES算法加密,DES的秘钥用RSA公钥密码中服务器的公钥加密,计算明文的Hash函数值,一起传送给客户端 4.客户端用RSA公钥密码中服务器的私钥解密DES的,秘钥,用秘钥对密文进行解密,得出明文.计算

实验五 Java网络编程及安全

北京电子科技学院 实      验      报      告 课程:移动平台应用开发实践  班级:201592   姓名:曾俊宏  学号:20159210 成绩:___________  指导老师:娄嘉鹏    实验日期 :2015.10.25 实验名称:                          Java 网络编程及安全 实验内容:      1.掌握 Socket程序的编写    2.掌握密码技术的使用    3.设计安全传输系统 我的实验搭档是蔡斌思    http://www.

java网络编程socket\server\TCP笔记(转)

java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04|  分类: Socket |  标签:java  |举报|字号 订阅 1 TCP的开销 a  连接协商三次握手,c->syn->s,s->syn ack->c, c->ack->s b  关闭协商四次握手,c->fin->s, s->ack-c,s->fin->c,c->ack->s c  保持数据有序,响应确认等计算开销 d

java网络编程与安全

北京电子科技学院(BESTI) 实     验    报     告 课程:JAVA程序设计  班级:1253   姓名:魏昊卿  小组伙伴:杨舒雯 学号:20135203   伙伴:20135324 成绩:             指导教师:娄嘉鹏          实验日期:2015.6.09 实验密级:  无     预习程度:            实验时间15:30~18:00 仪器组次:         必修/选修:选修                 实验序号:04 实验名称:ja