JAVA网络编程 ——基于TCP的Socket编程(1)——实现服务器端与客户端的实时对话

第一篇文章,我先介绍以及记录一下我所学的知识点。(总结了一下视频老师讲的东西)

一,HTTP与Socket

1.HTTP:超文本传输协议

特点:客户端发送的请求需要服务器端每次来响应,在请求结束之后主动释放连接,从建立连接到关闭连接称为“一次连接”,所以HTTP是“短连接”。

2.Socket(IP+PORT):是TCP/IP的封装与应用,它不是协议,而是API

特点:客户端与服务器之间一旦建立连接,就可以互相范松消息,也叫对话,但在实际应用中,通信双方经过许多的中间节点,比如,路由器,网关,防火墙,大部分防火墙会默认关闭长时间处于不活跃的状态连接,而是Socket断开。

选择:当服务器主要想客户端推送消息,为了保持客户端与服务器数据的实时与同步,通常会从采用HTTP协议,只要客户端定时向服务器端发送请求,同时也是在询问是否有新的数据,如果有那就传入客户端。

二,TCP/IP模型

1.通信原理图

2.模型图

                                                             

三,基于TCP的网络编程

1.Socket: IP地址+端口号组成了Socket,Socket是网络上运行程序之间双向通信的终结点,是TCP和UDP的基础。

2.JAVA提供的网络功能(可以查看API)

InetAddress:标识IP地址

URL:统一资源定位,通过URL可以直接读取或写入网络上的数据

Sockets:使用TCP协议实现Socket相关的类

Datagram:使用UDP协议。将数据保存在数据包中,通过网络通信。

3.Socket通信模型

4.代码(可直接粘贴复制,使用)请修改包名

1.服务器端线程类   ServerThread.class

//*******************服务器端线程类********************//
package com.NullChenHui;

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.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class ServerThread extends Thread {
	private int port;
	private boolean OVER_FLAG = false;
	public ServerThread(int port) {
		this.port = port;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
        /**
         * 使用无线循环或者有限循环来实现客户端与服务器的对话
         */
		try {
			//1.创建连接服务器的Socket 并绑定端口号
			ServerSocket ssocket = new ServerSocket(port);
			while(!OVER_FLAG) {
			//2.监听来自客户端的请求   并返回Socket实例
			Socket socket = ssocket.accept();
			//3.获取输入流  
			InputStream is = socket.getInputStream();  
			InputStreamReader  isr = new InputStreamReader(is);  //字节流包装为字符流
			BufferedReader bf = new BufferedReader(isr);   //添加进缓存
			//4.从缓存中读取数据
			String info = null;
			if("OVER".equals(info)) {
	        	OVER_FLAG = true;
	        	break;
	        }
			while((info=bf.readLine()) != null) {
				System.out.println("客户端说:"+info);
				if("OVER".equals(info)) {
		        	OVER_FLAG = true;
		        	break;
		        }
			}
			
			
			socket.shutdownInput();
			String data = null;
			System.out.print("服务端:");
			Scanner scanner = new Scanner(System.in);
	        String data1 = scanner.nextLine();
	        
			//回馈给客户端
			OutputStream os = socket.getOutputStream();
			 PrintWriter pw = new PrintWriter(os);
			//3.发送数据
			pw.write(data1);
			pw.flush();
			//4.关闭资源
			os.close();
			pw.close();
			is.close();
			bf.close();
//			socket.shutdownOutput();
			}
			System.out.println("对话结束");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}

2.服务器端主程序  MyServerSocket.class

package com.NullChenHui;
/**
 * 基于TCP的Socket的编程    服务端
 * @author NullChen
 *
 */
public class MyServerSocket{
	
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		System.out.println("***我是服务器***");
		ServerThread sThread = new ServerThread(3333);
		sThread.start();
	}
}

3.客户端线程类 ClientThread.class

package com.NullChenHui;

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;
import java.net.UnknownHostException;
import java.util.Scanner;

public class ClientThread extends Thread {
	private String IP;
	private int port;
	private boolean OVER_FLAG = false;
	public ClientThread(String IP ,int port) {
		this.IP = IP;
		this.port = port;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		OutputStream os =null;
		PrintWriter pw = null;
		
		try {
			//1.建立客户端Socket  并指定发送服务器端的地址(IP + port )
			
			//2.获取输出流
			 
			while(!OVER_FLAG) {
			 Socket socket = new Socket(IP,port);
			 os = socket.getOutputStream();
			 pw = new PrintWriter(os);
			//3.发送数据
			
			System.out.print("客户端:");
		    Scanner scanner = new Scanner(System.in);
		    String data1 = scanner.nextLine();
		 
			pw.write(data1);
			pw.flush();
			//4.关闭资源
			socket.shutdownOutput();	
			//接受来自服务器的反馈
			InputStream is = socket.getInputStream();  
			InputStreamReader  isr = new InputStreamReader(is);  //字节流包装为字符流
			BufferedReader bf = new BufferedReader(isr);   //添加进缓存
			//4.从缓存中读取数据
			String info = null;
			while((info=bf.readLine()) != null) {
				System.out.println("服务器说:"+info);
				if("OVER".equals(info)) {
		        	OVER_FLAG = true;
		        	break;
		        }
			}
			  
			/***
			 * 如果获取的内容是空的 说明服务器端还没有发送数据
			 */

			// 5 关闭资源
			os.close();
			pw.close();
			is.close();
			bf.close();
//			socket.shutdownInput();
		}
			System.out.println("对话结束");
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}

4.客户端主程序 MyClientSocket.class

package com.NullChenHui;

public class MyClientSocket{
	public static void main(String[] args) {
		System.out.println("***我是客户端***");
		ClientThread cThread = new ClientThread("127.0.0.1",3333);
		cThread.start();

	}
}

四,注意问题

1.先启动服务器端后启动客户端

2.两个之间的对话就是客户端说一句,服务器说一句。

3.以客户端以OVER结束对话

4.在关闭输入输出流的地方有点小问题。

五,欢迎大家指正。

Demo地址:https://download.csdn.net/download/h2677lucy/10292230

  • 13
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值