Socket网络编程

Socket网络编程

socket编程也叫套接字编程,应用程序可以通过它发送或者接受数据
套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信.
网络套接字是IP地址与端口号TCP协议的组合
Socket就是为网络编程提供的一种机制,通信的两端都有Socket
网络通信其实就是Socket之间的通信,数据在两个Socket之间通过I/O进行传输.

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。
四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发

1.直接显示到网页

public class Tomcat {
    public static void main(String[] args) throws IOException {
        //Java中服务的创建
        System.out.println("start server ...");
        //Java中网络编程中的服务对象类型为ServerSocket
        //构建服务,并在9999端口进行监听
        ServerSocket server=new ServerSocket(9999);

        //等待服务端的连接
        while(true){
            //这里的socket代表客户端对象
            Socket socket=server.accept();//阻塞式方法
            System.out.println("hello client "+socket);
            //获取向客户端输出数据的流对象
            OutputStream out=socket.getOutputStream();
            //向客户端写数据
            //out.write("hello".getBytes());//这种方式浏览器不会显示
            String content="HTTP/1.1 200\r\n" +//响应行
                    "Content-Type: text/html;charset=UTF-8\r\n"+//响应头
                    "\r\n"+//空行,
                    "<h1>hello client</h1>"; //数据
            out.write(content.getBytes());
            socket.close();
        }
    }
}

2.客户端和服务端

服务器:


/**本类用来表示Socket网络编程案例的服务器端
 * 完成步骤分析:
 * 1.启动服务器
 * 2.接收客户端的连接请求
 * 3.接收客户端发来的数据
 * */
/**测试注意事项:先启动服务器端,再启动客户端*/
public class Server {
	public static void main(String[] args) throws Exception {
		//1.启动服务器,指定端口号为8888,等待客户端的连接
		/**注意:
		 * 1.使用ServerSocket需要导包java.net.ServerSocket
		 * 2.此操作会抛出异常
		 * 3.指定的端口号范围是:0-655535,而0-1024是系统端口号,不能指定
		 * */
		ServerSocket ss = new ServerSocket(8888);
		//2.接收客户端的连接请求,并建立数据通信通道
		Socket socket = ss.accept();
		//3.获取到读取流,接收并读取客户端发来的数据
		InputStream in = socket.getInputStream();
		//通过循环挨个读取显示读到的内容
		for(int i = 0;i < 5;i++) {
			//int b = in.read();//此方法读取的结果是把字符转成数字
			char c = (char) in.read();//为了直接显示读取到的字符,需要强制类型转换(大转小,int转char)
			System.out.print(c);//print()同行输出,注意细节哦
		}
		//5.给客户端发送数据
		OutputStream out = socket.getOutputStream();
		out.write("world".getBytes());
		out.flush();
		
		//4.释放资源
		/**注意关流的顺序,后出现的先关闭*/
		in.close();
		ss.close();
	}
}

客户端:

/**本类用来表示Socket网络编程案例的客户端
 * 完成步骤分析:
 * 1.指定要连接的服务器
 * 2.给服务器发送hello
 * */
public class Client {
	public static void main(String[] args) throws Exception {
		//1.指定要连接的服务器,需要同时指定服务器的IP & Port
		/**注意:
		 * 1.使用Socket需要导包java.net.Socket
		 * 2.此操作会抛出异常
		 * 3.如果使用的是本机的IP,地址是固定值,用来测试时使用127.0.0.1
		 * */
		Socket socket = new Socket("127.0.0.1",8888);
		//2.给服务器端发送hello
		OutputStream out = socket.getOutputStream();
		//把要输出的数据hello字符串转变成byte[]的形式进行输出
		out.write("hello".getBytes());
		out.flush();
		
		//4.读取从服务器端返回的数据
		InputStream in = socket.getInputStream();
		for (int i = 0; i < 5; i++) {
			char c = (char) in.read();//为了显示字符而不是数字,强制类型转换成char
			System.out.print(c);//不换行展示获取到的数据
		}
		
		//3.释放资源
		//out.close();
		socket.close();
		
	}
}

3.流

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**这个类用来当做回声案例的服务器端
 * 1.启动服务器
 * 2.接收客户端的连接请求
 * 3.给每个用户分配对应的话务员
 * 4.话务员:主要负责和对应的客户端对象进行沟通I/O
 * */
/**1.创建优化后的Server2类,充当服务器端*/
public class Server2 {
	/**2.创建方法,负责服务多个客户*/
	public void service() {
		/**3.匿名对象+匿名内部类(重写run方法)*/
		new Thread() {
			/**5.把业务写在run()中*/
			@Override
			public void run() {
				try {
					//5.1 启动服务器,设置端口号为8000并等待客户端连接
					ServerSocket ss = new ServerSocket(8000);
					System.out.println("服务器启动成功!");
					while(true) {//死循环,一直accept,也就是接受客户端的连接请求
						//5.2 一直接受所有客户端的连接请求
						Socket socket = ss.accept();
						System.out.println("客户端连接成功!");
						//5.3 给每个客户分配自己对应的话务员,1v1
						HuaWuThread t = new HuaWuThread(socket);
						t.start();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			};
		}.start();/**4.启动线程*/
	}
	
	/**6.创建话务员内部类,主要负责和客户端沟通 I/O*/
	class HuaWuThread extends Thread{
		//6.1 定义本类中的成员变量socket,用来保持通话
		Socket socket;
		//6.2含参构造,接受当前的连接信息,保持通话,为谁服务就保存谁的数据
		public HuaWuThread(Socket socket) {
			this.socket = socket;
		}
		//6.3把话务员的业务放在run(),一直读取客户端发来的数据,并作出回应
		@Override
		public void run() {
			try {
				//7.1读取一行BufferedReader,并且写出一行PrintWriter --双向流
				BufferedReader in = new BufferedReader(
						new InputStreamReader(socket.getInputStream()));
				PrintWriter out = new PrintWriter(
						new OutputStreamWriter(socket.getOutputStream()));
				//7.2读取客户端发来的一行数据
				String line;//定义变量,记录读取到的一行数据
				while((line = in.readLine()) != null) {//只要有数据就一直读
					System.out.println("客户端发来的数据:"+line);
					//7.1可以给客户端作出响应-接收键盘输入的响应
					System.out.println("请输入您的回应:");
					String input = new Scanner(System.in).nextLine();
					//7.2发出作为服务器的响应
					out.println(input);
					out.flush();//把数据刷出去
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		Server2 s = new Server2();
		s.service();
	}
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

/**本类用来做回声案例的客户端
 * 1.连接指定的服务器
 * 2.给服务器发送数据
 * 3.接收服务器响应的数据
 * */
public class Client2 {
	public static void main(String[] args) {
		try {
			//1.连接指定的服务器,同时指定服务器的IP和端口号
			Socket socket = new Socket("127.0.0.1",8000);
			//2.给服务器发送数据
			while(true) {
				//向服务器写出一行数据,并且读取服务器响应回来的数据
				PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
				BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				//3.通过流对象进行发送和读取的操作
				System.out.println("请输入您想给服务器发送的数据:");
				String input = new Scanner(System.in).nextLine();
				out.println(input);//向服务端发送指定数据
				out.flush();//把数据刷出去
				String line = in.readLine();//读取回声数据
				System.out.println("服务器端响应的数据是:"+line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值