admin 管理员组

文章数量: 887021

网络编程。。

Socket简介

什么是Socket?

  1. Socket的底层机制复杂,Java平台提供了一些简单的API,可以更简单有效的使用Socket开发而无需了解底层机制

  2. 通信链路的端点就被称为“套接字”(英文名Socket)是提供给应用程序的接口

基于TCP协议的Socket编程

基于TCP协议的Socket网络通信

用来实现双向安全连接网络通信

Socket通信模型

进行网络通信时,Socket需要借助数据流来完成数据的传递工作

 

Socket网络编程一般可以分成如下步骤进行

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
​
public class Client {
​public static void main(String[] args) {Socket socket = null;OutputStream os = null;InputStream is = null;BufferedReader br = null;try {//创建通信链路的端点客户端套接字socket = new Socket("127.0.0.1", 8888);//获取输出流将数据发送出去os = socket.getOutputStream();String str = "用户名:zhangsan 密码:123456";os.write(str.getBytes());System.out.println("我是客户端,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is = socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result = br.readLine();System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{           try {               br.close();is.close();os.close();socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}
​}}
}
​
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
​
public class Server {
​public static void main(String[] args) {ServerSocket ss= null;Socket socket = null;InputStream is = null;BufferedReader br = null;OutputStream os = null;try {//创建服务器端套接字ServerSocketss= new ServerSocket(8888);//服务器通过调用侦听方法来获取客户端的请求socket = ss.accept();//通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息is = socket.getInputStream();//通过输入流读取客户端发送的消息br = new BufferedReader(new InputStreamReader(is));String str = br.readLine();System.out.println("我这边是服务器:客户端发送给我的数据是:"+str);//关闭通道socket.shutdownInput();//服务器接收客户端消息后,需要给客户端一个响应信息os = socket.getOutputStream();String result = "用户名和密码正确,可以登录";os.write(result.getBytes());System.out.println("给客户端的响应信息发送成功");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {os.close();br.close();is.close();socket.close();ss.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}                   }   }
}

Socket中实现对象的传递

传递对象信息

 

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
​
public class Server {
​public static void main(String[] args) {ServerSocket ss= null;Socket socket = null;InputStream is = null;ObjectInputStream ois =null;OutputStream os = null;try {//创建服务器端套接字ServerSocketss= new ServerSocket(8888);//服务器通过调用侦听方法来获取客户端的请求socket = ss.accept();//通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息is = socket.getInputStream();//通过输入流读取客户端发送的消息ois = new ObjectInputStream(is);Student student = (Student)ois.readObject();System.out.println("我这边是服务器:客户端发送给我的数据是:"+student);//关闭通道socket.shutdownInput();//服务器接收客户端消息后,需要给客户端一个响应信息os = socket.getOutputStream();String result = "获取的对象姓名和年龄正确";os.write(result.getBytes());System.out.println("给客户端的响应信息发送成功");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {os.close();ois.close();is.close();socket.close();ss.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}
​
import java.io.Serializable;
​
public class Student implements Serializable {private String name;private int age;
​public Student() {super();}
​public Student(String name, int age) {super();this.name = name;this.age = age;}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
​public int getAge() {return age;}
​public void setAge(int age) {this.age = age;}
​@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}
​
}
​
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
​
public class Client {
​public static void main(String[] args) {Socket socket = null;OutputStream os = null;ObjectOutputStream oos = null;InputStream is = null;BufferedReader br = null;try {//创建通信链路的端点客户端套接字socket = new Socket("127.0.0.1", 8888);//获取输出流将数据发送出去os = socket.getOutputStream();Student student = new Student("张三", 23);oos = new ObjectOutputStream(os);oos.writeObject(student);System.out.println("我是客户端,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is = socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result = br.readLine();System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{           try {               br.close();is.close();oos.close();os.close();socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}
​}}
}
​

多线程处理多请求

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
​
import cn.bdqn.demo03.Student;
​
public class Client1 {public static void main(String[] args) {Socket socket = null;OutputStream os = null;ObjectOutputStream oos = null;InputStream is = null;BufferedReader br = null;try {//创建通信链路的端点客户端套接字socket = new Socket("127.0.0.1", 8888);//获取输出流将数据发送出去os = socket.getOutputStream();Student student = new Student("张三", 23);oos = new ObjectOutputStream(os);oos.writeObject(student);System.out.println("我是客户端1,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is = socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result = br.readLine();System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{           try {               br.close();is.close();oos.close();os.close();socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}
​}}
}
​
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
​
import cn.bdqn.demo03.Student;
​
public class Client2 {public static void main(String[] args) {Socket socket = null;OutputStream os = null;ObjectOutputStream oos = null;InputStream is = null;BufferedReader br = null;try {//创建通信链路的端点客户端套接字socket = new Socket("127.0.0.1", 8888);//获取输出流将数据发送出去os = socket.getOutputStream();Student student = new Student("李四", 23);oos = new ObjectOutputStream(os);oos.writeObject(student);System.out.println("我是客户端2,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is = socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result = br.readLine();System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{           try {               br.close();is.close();oos.close();os.close();socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}
​}}
}
​
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
​
import cn.bdqn.demo03.Student;
​
public class Client3 {public static void main(String[] args) {Socket socket = null;OutputStream os = null;ObjectOutputStream oos = null;InputStream is = null;BufferedReader br = null;try {//创建通信链路的端点客户端套接字socket = new Socket("127.0.0.1", 8888);//获取输出流将数据发送出去os = socket.getOutputStream();Student student = new Student("王五", 23);oos = new ObjectOutputStream(os);oos.writeObject(student);System.out.println("我是客户端3,我将数据发送完毕");//关闭通道socket.shutdownOutput();//客户端需要通过输入流读取服务器端发送过来的消息is = socket.getInputStream();br = new BufferedReader(new InputStreamReader(is));String result = br.readLine();System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{           try {               br.close();is.close();oos.close();os.close();socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}
​}}
}
​
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
​
public class Server {/** 多个客户端向服务器发送请求,服务器怎么办???* * * 客户端跟之前客户端做的事情没有任何改变*      客户端通过输出流发送请求信息*      客户端通过输入流获取服务器端的响应信息* 服务器端做的事情跟之前服务器端做的事情不一样*      服务器端循环去侦听客户端的请求,侦听到一个请求就会获取一个Socket类对象,* 将这个Socket类对象作为参数传递给服务器线程类的有参构造方法里去* 服务器线程类通过获取到的Socket类对象去执行原来服务器所做的事情*      通过输入流获取客户端的请求信息*      通过输出流发送响应信息给客户端* */public static void main(String[] args) {ServerSocket ss = null;Socket socket = null;try {//创建ServerSocket类对象ss = new ServerSocket(8888);while(true){socket = ss.accept();//将获取到的socket对象传递到线程类中ServerThread st = new ServerThread(socket);st.start();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {socket.close();ss.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}
​}}
​
}
​
​
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
​
public class ServerThread extends Thread {
​//声明一个Socket类型的属性private Socket socket;
​public ServerThread(Socket socket) {super();this.socket = socket;}
​@Overridepublic void run() {InputStream is =null;ObjectInputStream ois =null;OutputStream os =null;  try {//通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息is = socket.getInputStream();ois = new ObjectInputStream(is);Student student = (Student)ois.readObject();System.out.println("我这边是服务器:客户端发送给我的数据是:"+student);
​//关闭通道socket.shutdownInput();
​//服务器接收客户端消息后,需要给客户端一个响应信息
​os =socket.getOutputStream();String result = "获取的对象姓名和年龄正确";byte[] bytes = result.getBytes();os.write(bytes);System.out.println("给客户端的响应信息发送成功");
​} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {os.close();ois.close();is.close();socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
​
}
import java.io.Serializable;
​
public class Student implements Serializable {private String name;private int age;
​public Student() {super();}
​public Student(String name, int age) {super();this.name = name;this.age = age;}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
​public int getAge() {return age;}
​public void setAge(int age) {this.age = age;}
​@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}
​
}
​

基于UDP协议的Socket编程

 

基于UDP协议的Socket网络编程步骤

 

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.Scanner;
​
​
public class Receive {
​public static void main(String[] args) {/** 示例06:升级示例05,发送方发送咨询问题,接收方回应咨询。* * 接收方实现步骤如下: * (1)创建DatagramPacket对象,准备接收封装的数据。* (2)创建DatagramSocket对象,接收数据保存于DatagramPacket对象中。* (3)利用DatagramPacket对象处理数据。*/Scanner sc  = new Scanner(System.in);DatagramSocket ds = null;DatagramPacket dp = null;DatagramPacket dpto = null;// 创建DatagramPacket对象,用来准备接收数据byte[] buf = new byte[1024];dp = new DatagramPacket(buf, 1024);while(true){try {// 创建DatagramSocket对象,接收数据ds = new DatagramSocket(8800);ds.receive(dp);// 显示接收到的信息String mess = new String(dp.getData(), 0, dp.getLength());System.out.println(dp.getAddress().getHostAddress() + "说:" + mess);
​String reply = sc.nextLine();// 显示与本地对话框System.out.println("我  说:" + reply);// 创建DatagramPacket对象,封装数据SocketAddress sa = dp.getSocketAddress();dpto = new DatagramPacket(reply.getBytes(),reply.getBytes().length, sa);ds.send(dpto);} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {ds.close();}}
​}
​
}
​
​
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
​
public class Send {/** 示例06:升级示例05,发送方发送咨询问题,接收方回应咨询。* * 发送方实现步骤如下: * (1)获取本地主机的InetAddress对象。 * (2)创建DatagramPacket对象,封装要发送的信息。* (3)利用DatagramSocket对象将DatagramPacket对象数据发送出去。*/
​public static void main(String[] args) {Scanner sc = new Scanner(System.in);DatagramSocket ds = null;InetAddress ia = null;while(true){String mess = sc.nextLine();System.out.println("我说:" + mess);try {// 获取本地主机地址ia = InetAddress.getByName("localhost");// 创建DatagramPacket对象,封装数据DatagramPacket dp = new DatagramPacket(mess.getBytes(),mess.getBytes().length, ia, 8800);// 创建DatagramSocket对象,向服务器发送数据ds = new DatagramSocket();ds.send(dp);
​byte[] buf = new byte[1024];DatagramPacket dpre = new DatagramPacket(buf, buf.length);ds.receive(dpre);// 显示接收到的信息String reply = new String(dpre.getData(), 0, dpre.getLength());System.out.println(dpre.getAddress().getHostAddress() + "说:"+ reply);} catch (UnknownHostException e) {e.printStackTrace();} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {ds.close();}}}
}
​

本文标签: 网络编程