Socket通信

参考博客:http://blog.youkuaiyun.com/x_and_y/article/details/53067450

Socket通信

ip地址和端口组成了Socket。

Socket与ServerSocket的交互,下面的图片我觉得已经说的很详细很清楚了。


服务器端:ServerSocket类

客户端:Socket类

1、Socket通信实现步骤

(1)创建ServerSocket和Socket

(2)打开连接到Socket的输入输出流

(3)按照协议对Socket进行读写操作

(4)关闭输入输出流,关闭Socket


2、服务器端

(1)创建ServerSocket对象,绑定监听端口

(2)通过accept()方法监听客户端请求

(3)连接建立后,通过输入流读取客户端发送的请求信息

(4)通过输出流向客户端发送响应信息

(5)关闭相关资源


3、客户端

(1)创建Socket对象,指明需要连接的服务器的地址和端口

(2)连接建立后,通过输入流向服务器发送请求信息

(3)通过输出流获取服务器响应的信息

(4)关闭相关资源



4、套接字:

客户端和服务器之间要进行通信首先要建立连接,然后才能在这个连接上收发字节流。

       套接字就是连接的一个端点,每个套接字都有一个套接字地址,由32位整数IP地址和16位整数端口号组成,用“IP地址:端口号”表示。这就好比要在宿舍楼找到一个人,不仅要知道他的楼栋号(IP),还要知道房间号(端口)。

      一个连接由两端的套接字地址唯一确定,称为套接字对。

(client address: client port, server address: server port)

      其中客户端的端口是临时分配的端口,服务器的端口是固定的知名端口。

     Java中的服务器套接字是ServerSocket,客户端套接字是socket。两者建立连接后,就能通过输入输出流进行通信了(服务器的输入流对应客户端的输出流,服务器的输出流对应客户端的输入流)。


5、Socket和ServerSocket的常用方法

(1)Socket常用方法摘要

构造方法摘要



常用方法摘要







(2)ServerSocket

构造方法类



常用方法类



6、经典的例子

多线程服务器:

应用多线程来实现服务器与多客户端之间的通信


(1)服务器端

package test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;


public class Server {
	public static void main(String[] args) {
		try {
			//1、创建服务器端Socket,即ServerSocket
		        //指定绑定的端口,并监听此端口
			ServerSocket serverSocket=new ServerSocket(8888);
			Socket socket=null;
			//记录客户端数量
			int count=0;
			//2、调用accept()方法开始监听,等待客户端的连接
			System.out.println("***服务器即将启动,等待客户端的连接***");
			//循环监听等待客户端的连接
			while(true){
				//调用accept()方法开始监听,等待客户端的连接
				socket=serverSocket.accept();
				//创建一个新的线程
				ServerThread serverThread=new ServerThread(socket);
				//启动线程
				serverThread.setPriority(4);
				serverThread.start();
				count++;
				System.out.println("客户端数量:"+count);
				InetAddress address=socket.getInetAddress();
				System.out.println("当前客户端的ip:"+address.getHostAddress());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
(2)服务器线程处理类


package test;
/*
 * 服务器线程处理类
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class ServerThread extends Thread {
	//和本线程相关的socket
	Socket socket=null;
	public ServerThread(Socket socket){
		this.socket=socket;
	}
	//线程执行的操作,响应客户端的请求
	public void run(){
		InputStream is=null;
		//将字节流转换为字符流
		InputStreamReader isr=null;
		//为输入流添加缓冲
		BufferedReader br=null;
		OutputStream os=null;
		//包装为打印流
		PrintWriter pw=null;
		try {
			is = socket.getInputStream();
			isr = new InputStreamReader(is);
			br = new BufferedReader(isr);
			String info=null;
			while((info=br.readLine())!=null){
				//循环读取客户端的信息
				System.out.println("我是服务器,客户端说"+info);
			}
			socket.shutdownInput();
			os = socket.getOutputStream();
			pw = new PrintWriter(os);
			pw.write("欢迎您");
			pw.flush();//调用flush()方法,将缓冲输出
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//5、关闭资源
			try {
				if(pw!=null){
					pw.close();
				}
				if(os!=null){
					os.close();
				}
				if(br!=null){
					br.close();
				}
				if(isr!=null){
					isr.close();
				}
				if(is!=null){
					is.close();
				}
				if(socket!=null){
					socket.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	
}

(3)客户端类

package test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
	public static void main(String[] args) {
		
		try {
			//1、创建客户端socket,指定服务器地址和端口
			Socket socket=new Socket("localhost", 8888);
			//2、获取输出流,向服务器端发送信息
			OutputStream os=socket.getOutputStream();//字节输出流
			PrintWriter pw=new PrintWriter(os);//将输出流包装为打印流
			pw.write("用户名:admin;密码:123");
			pw.flush();
			socket.shutdownOutput();
			//3、获取输入流,用来读取服务器端的响应信息
			InputStream is=socket.getInputStream();
			BufferedReader br=new BufferedReader(new InputStreamReader(is));
			String info=null;
			while((info=br.readLine())!=null){
				
				System.out.println("我是客户端,服务器说"+info);
			}
			
			//4、关闭资源
			br.close();
			is.close();
//			pw.close();
			os.close();
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		
	
	}
}


InetAddress

InetAddress 类提供将主机名解析为其 IP 地址(或反之)的方法。 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值