Socket编程基础--基于TCP协议的网络编程
来源:互联网 发布:java api在线 编辑:程序博客网 时间:2024/06/05 05:16
一、概述
在学习TCP协议之前,需要了解网络编程中的几个基本概念。
- IP协议:是Internet Protocol的外语缩写,为计算机网络相互连接进行通信而设计的协议。在因特网中,它是能使连接到网上的所有计算机网络实现相互通信的一套规则,规定了计算机在因特网上进行通信时应当遵守的规则。任何厂家生产的计算机系统,只要遵守IP协议就可以与因特网互连互通。IP地址具有唯一性。
- TCP协议:TCP协议被称作是一种端对端协议。它提供IP环境下的数据可靠传输,提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送
- 端口号Port:主要是计算机用来来区分连接不同应用程序。注意:0-1023不可以使用,系统已经占用。
二、Java的基本网络支持
- 使用InetAddress
- URLDecoder和URLEncoder
URL、URLConnetction(这个后面说)
InetAddress的简单使用
public static void main(String[] args) throws Exception { InetAddress ia = InetAddress.getLocalHost() ; System.out.println("ip:" + ia.getHostAddress()); System.out.println("主机名:" + ia.getHostName()); }
URLDecoder和URLEncoder
URLDecoder和URLEncoder是完成字符串和application/x-www-form-urlencode MIME字符串之间的相互转化
- URLDecoder的decode()方法可以将一个看上去是乱码的转换成不是乱码的字符串
- URLEncoder的encode()方法可以将一个看上去不是乱码的转换成是application/x-www-form-urlencode MIME的字符串
public static void main(String[] args) throws Exception { String keyword = URLEncoder.encode("李文"); System.out.println(keyword); keyword = URLDecoder.decode(keyword) ; System.out.println(keyword); }
三、通信流程
服务端
计算机能够接受通信实体请求的类是ServerSocket,ServerSocket用来监听客户端对应的socket,一般我们在while(true)里使用ServerSocket不断的获取socket,如果没用连接它会处于等待状态。
常用api:
- accept():获取一个客户端socket的连接请求,这个方法会返回一个与客户端对应的socket,否则会处于等待状态,线程阻塞。
- ServerSocket(int port):用指定端口号创建一个ServerSocket该值可以在0-65535之间。上面已经提过,0-1023不要用。
- ServerSocket(int port,int backlog):增加一个改变连接队列长度的参数。
//1.创建socketserver,监听3000端口 ServerSocket ss = new ServerSocket(30000) ; while(true){ Socket s = ss.accept(); //2.将输出流包装成PrintStream PrintStream ps = new PrintStream(s.getOutputStream()) ; //3.进行IO操作 ps.println("hello socket,i am from SocketServer"); //4.关流 ps.close(); s.close() ; }
客户端
客户端通常使用Socket的构造器连接指定服务器
构造函数如下: public Socket(String host, int port)
使用如下:
//1.创建socket Socket s = new Socket("127.0.0.1",30000) ; BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())) ; String line = br.readLine(); System.out.println("来自服务端:" + line ); s.close() ;
上面的127.0.0.1是连接本地IP的。大家可以到C:\Windows\System32\drivers\etc这个目录下的host文件中查看到。
上面程序运首先要运行服务端,然后在运行客户端就可以进行通信了。
当服务端、客户端连接到了对应的socket之后,程序就不用再区分服务端、客户端了,两者是通过各自的socket通信。socket通过如下两个api来获取输出流、输入流。
public InputStream getInputStream() public OutputStream getOutputStream()
四、加入多线程
上面的client、server只是简单的通信,下面实现一个包含多线程的socket通信。我们在服务端创建多线程线程,每一个socket对应一个线程,这个线程负责读取socket输入流中的内容,也就是从客户端发送过来的数据,然后再返回给客户端信息表示收到了。
服务端代码:
public static ArrayList<Socket> socketList = new ArrayList<Socket>() ; public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(30001) ; while(true){ Socket s = ss.accept() ; //每次获取一个socket,添加到集合中 socketList.add(s) ; //开启线程执行任务 new Thread(new ServerThread(s)).start(); } }
服务端创建一个集合用来存放来自客户端的Socket,每当获取一个socket,就开始启动一个线程,该线程用来处理通信业务。
class ServerThread implements Runnable{ //处理的socket Socket s = null ; //处理socket对应的流 BufferedReader br = null ; public ServerThread(Socket s ) throws IOException{ this.s = s ; br = new BufferedReader(new InputStreamReader(s.getInputStream())) ; } public void run() { String context ; while((context=readFromClient())!= null ){ for (Socket s : MyServer.socketList) { System.out.println("服务端收到数据了:" + context ); PrintStream ps; try { ps = new PrintStream(s.getOutputStream()); ps.println(context + "---来自服务端"); } catch (IOException e) { e.printStackTrace(); } } } } public String readFromClient(){ try { return br.readLine(); } catch (IOException e) { e.printStackTrace(); //删除socket MyServer.socketList.remove(s); } return null ; }}
客户端代码:
public static void main(String[] args) { //1.创建socket try { Socket s = new Socket("127.0.0.1",30001) ; //2.获取来自服务端的数据 new Thread(new ClientThread(s)).start() ; //3.获取socket对应的输出流 PrintStream ps = new PrintStream(s.getOutputStream()) ; String line = null ; //4.键盘输入 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ; while((line = br.readLine())!= null ){ //5.将键盘输入写到socket输出流中 ps.println(line); } } catch (Exception e) { e.printStackTrace(); } }
重要的地方已经注释,代码不同,相信能看懂。这样就完成了多线程的通信了,还是和上面一样,先运行server,再运行client,通过运行可以知道每个客户端可以看到其它客户端的信息。
Ok,这篇已经结束了,这篇只是简单介绍了Socket的基础,后面会继续详细分析还有介绍基于UDP网络编程。
源码下载
- Socket编程基础--基于TCP协议的网络编程
- 基于TCP协议的网络编程--socket编程(1)
- 基于TCP协议的网络编程--socket编程(2)
- 基于TCP/IP协议的网络编程—Socket编程
- socket编程-- 基于TCP协议的网络程序
- socket编程-- 基于TCP协议的网络程序
- socket编程-- 基于TCP协议的网络程序
- 基于TCP协议的网络通信(socket编程)
- Windows 网络编程基于TCP协议的Socket通信
- 网络编程----基于TCP的socket编程
- 基于TCP协议的socket编程实例
- 基于TCP协议的socket编程实例
- 基于TCP/IP协议的socket编程
- 基于TCP协议下的socket编程
- 基于TCP/IP协议的Socket编程
- 基于TCP的socket编程网络掉线重连
- 基于TCP的Socket网络编程
- Linux网络编程之[基于socket通信的tcp协议的编程模型]
- Finished with non-zero exit value *
- 李开复万字长文科普人工智能:AI是什么 将带我们去哪儿?
- 存储班长信息的学生类
- 10个深度学习的工具
- Java 对象和类
- Socket编程基础--基于TCP协议的网络编程
- a标签 href 和 onclock
- 【Android】使用MediaCodec硬编码实现视频直播推流端(一)
- 6、Android Content Provider测试
- C#中将图片的背景去除
- 人数不定的工资类
- Small PDF
- 你的项目有潜在的问题吗?有关项目管理的方式方法
- opencv内存管理器1