java编程_socket_套接字_网络编程
来源:互联网 发布:java奇数偶数的和 编辑:程序博客网 时间:2024/06/07 19:55
============================================================
1.实现server和client模型程序
============================================================
实现原理:
============================================================
服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,
在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),
等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
============================================================
客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,
关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
============================================================
服务器端代码:
- package com.basic.socket.server;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- /**
- * 服务器断的工作就是在指定的端口上监听
- * 1、建立连接
- * 2、打开输出流
- * 3、封装输出流
- * 4、向客户端发送数据
- * 5、关闭打开的输出流
- * 6、关闭打开的socket对象
- *
- * @author HP
- *
- * @time 2013-12-07
- *
- * @version 1.0
- */
- public class Chat_Server {
- public static void main(String[] args) {
- try {
- // 指定服务器端的端口号为8888
- ServerSocket s=new ServerSocket(8888);
- while(true){
- //建立连接
- Socket socket=s.accept();
- //打开输出流
- OutputStream os=socket.getOutputStream();
- //封装输出流
- DataOutputStream dos=new DataOutputStream(os);
- //s.getInetAddress()获取远程ip地址,s.getPort()远程客户端的断后好
- //向客户端发送数据
- dos.writeUTF("你好,客服端地址信息:"+socket.getInetAddress()+"\t客服端通讯端口号:"+socket.getPort());
- dos.writeUTF("i'm a server ,my name is Mercury!");
- //关闭打开的输出流
- dos.close();
- //关闭打开的socket对象
- socket.close();
- } //开始下一次循环
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- package com.basic.socket.client;
- import java.io.DataInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.Socket;
- /**
- * 1、创建socket对象,指定服务器的ip地址,和服务器监听的端口号
- * 2、打开输入流
- * 3、封装输入流
- * 4、打印服务器端发送过来的信息
- * 5、关闭输入流
- * 6、关闭打开的socket对象
- *
- * 客服端
- *
- * @author HP
- *
- * @time 2013-12-07
- *
- * @version 1.0
- */
- public class Chat_Client {
- public static void main(String[] args) {
- try {
- // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号
- // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么
- // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection
- // refused: connect
- Socket socket=new Socket("127.0.0.1",8888);
- // 打开输入流
- InputStream is=socket.getInputStream();
- // 封装输入流
- DataInputStream dis=new DataInputStream(is);
- // 打印服务器端发送过来的信息
- System.out.println(dis.readUTF());
- System.out.println(dis.readUTF());
- // 关闭输入流
- dis.close();
- // 关闭打开的socket对象
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
如果服务器端没有打开,这时候运行客户端,出现的结果:
- java.net.ConnectException: Connection refused: connect
- at java.net.PlainSocketImpl.socketConnect(Native Method)
- at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
- at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
- at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
- at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
- at java.net.Socket.connect(Socket.java:518)
- at java.net.Socket.connect(Socket.java:468)
- at java.net.Socket.<init>(Socket.java:365)
- at java.net.Socket.<init>(Socket.java:179)
- at com.b510.socket1703.TestClient.main(TestClient.java:19)
1 你好,客户端地址信息: /127.0.0.1 客户端通信端口号: 197122 i'm a server ,my name is Mercury!
============================================================
2.实现单线程的聊天室
============================================================
服务器端代码:
- package com.basic.socket.server;
- import java.io.BufferedReader;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.net.SocketException;
- /**
- * 服务器断的工作就是在指定的端口上监听
- * 1、建立连接
- * 2、打开输出流
- * 3、封装输出流
- * 4、向客户端发送数据
- * 5、关闭打开的输出流
- * 6、关闭打开的socket对象
- *
- * @author HP
- *
- * @time 2013-12-07
- *
- * @version 1.0
- */
- public class Chat_Server_Simple {
- public static void main(String[] args) {
- try {
- // 指定服务器端的端口号为8888
- ServerSocket s=new ServerSocket(8888);
- //建立连接
- Socket socket=s.accept();
- //打开输出流
- OutputStream os=socket.getOutputStream();
- //封装输出流
- DataOutputStream dos=new DataOutputStream(os);
- //打开输入流
- InputStream is=socket.getInputStream();
- //封装输入流
- DataInputStream dis=new DataInputStream(is);
- //读取键盘输入流
- InputStreamReader isr=new InputStreamReader(System.in);
- //封装键盘输入流
- BufferedReader br=new BufferedReader(isr);
- String info;
- while(true){
- //接受客户端发送过来的信息
- info=dis.readUTF();
- //打印接受的信息
- System.out.println("对方说: " + info);
- //如果发现接受的信息为:bye,那么就结束对话
- if(info.equals("bye"))
- break;
- //读取键盘的输入流
- info=br.readLine();
- //写入到网络连接的另一边,即客户端
- dos.writeUTF(info);
- //如果服务器自己说:bye,也是结束对话
- if(info.equals("bye"))
- break;
- } //开始下一次循环
- //关闭打开的输入流
- dis.close();
- //关闭打开的输出流
- dos.close();
- //关闭打开的socket对象
- socket.close();
- s.close();
- } catch (SocketException e) {
- System.out.println("网络连接异常,程序退出!");
- }catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
客户端代码:
- package com.basic.socket.client;
- import java.io.BufferedReader;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.net.Socket;
- /**
- * 1、创建socket对象,指定服务器的ip地址,和服务器监听的端口号
- * 2、打开输入流
- * 3、封装输入流
- * 4、打印服务器端发送过来的信息
- * 5、关闭输入流
- * 6、关闭打开的socket对象
- *
- * 客服端
- *
- * @author HP
- *
- * @time 2013-12-07
- *
- * @version 1.0
- */
- public class Chat_Client_Simple {
- public static void main(String[] args) {
- try {
- // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号
- // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么
- // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection
- // refused: connect
- Socket socket=new Socket("localhost",8888);
- //打开输出流
- OutputStream os=socket.getOutputStream();
- //封装输出流
- DataOutputStream dos=new DataOutputStream(os);
- // 打开输入流
- InputStream is=socket.getInputStream();
- // 封装输入流
- DataInputStream dis=new DataInputStream(is);
- //读取键盘输入流
- InputStreamReader isr=new InputStreamReader(System.in);
- //封装键盘输入流
- BufferedReader br=new BufferedReader(isr);
- String info;
- while(true){
- //客户端先读取键盘输入信息
- info = br.readLine();
- //把他写入到服务器方
- dos.writeUTF(info);
- //如果客户端自己说:bye,即结束对话
- if(info.equals("bye"))
- break;
- //接受服务器端信息
- info = dis.readUTF();
- //打印
- System.out.println("对方说: " + info);
- //如果服务器自己说:bye,也是结束对话
- if(info.equals("bye"))
- break;
- }
- //关闭相应的输入流,输出流,socket对象
- dis.close();
- dos.close();
- // 关闭打开的socket对象
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
运行效果:
服务器端效果>>>
- 对方说: hell
- 你好
- 对方说: 嘿嘿
- 你今天
- 对方说: 13
- 代售点
- hell
- 对方说: 你好
- 嘿嘿
- 对方说: 你今天?
- 13
- 对方说: 代售点?
当前的程序不管是服务器端,还是客户端,都是单线程的。如: 服务器端说:"你好"
- 1 //读取键盘的输入流
- 2 info = br.readLine();
- 3 //写入到网络连接的另一边,即客户端
- 4 dos.writeUTF(info);
- 5 //如果服务器自己说:bye,也是结束对话
通过上面的代码,把"你好"发送出去了,这时候,程序又开始循环,运行到:
- 1 //接受客户端发送过来的信息
- 2 info = dis.readUTF();
这段代码,其实在这里就阻塞在这里了。要等到客户端那边说了话,"嘿嘿",这时候这里的
阻塞才会变为非阻塞状态,然后又继续说,说完后又继续阻塞......
而对于客户端来说,其实是一样的道理,客户端说完"hello"后,进入:
- 1 //接受服务器端信息
- 2 info = dis.readUTF();
到收听服务器端的信息,在这里也产生了阻塞,只有服务器端说了"你好",这个阻塞才变为非阻塞
状态。然后又继续接下来的动作....
============================================================
3.实现多线程的聊天室
============================================================
服务器端代码:
- package com.basic.socket.server;
- import java.io.BufferedReader;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- 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 Test_Chat_Server {
- public static void main(String args[]) {
- try {
- // 创建一个socket对象
- ServerSocket s = new ServerSocket(8888);
- // socket对象调用accept方法,等待连接请求
- Socket s1 = s.accept();
- // =========服务器端,在这里应该先打开输出流,在打开输入流,
- // =========因为服务器端执行的操作是先听,再说,听,说,听,说.....
- // 打开输出流
- OutputStream os = s1.getOutputStream();
- // 封装输出流
- DataOutputStream dos = new DataOutputStream(os);
- // 打开输入流
- InputStream is = s1.getInputStream();
- // 封装输入流
- DataInputStream dis = new DataInputStream(is);
- // 创建并启用两个线程
- new MyServerReader(dis).start();
- new MyServerWriter(dos).start();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- // 接受并打印客户端传过来的信息
- class MyServerReader extends Thread {
- private DataInputStream dis;
- public MyServerReader(DataInputStream dis) {
- this.dis = dis;
- }
- public void run() {
- String info;
- try {
- while (true) {
- // 如果对方,即客户端没有说话,那么就会阻塞到这里,
- // 这里的阻塞并不会影响到其他线程
- info = dis.readUTF();
- // 如果状态有阻塞变为非阻塞,那么就打印接受到的信息
- System.out.println("对方说: " + info);
- if (info.equals("bye")) {
- System.out.println("对方下线,程序退出!");
- System.exit(0);
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- // 从键盘获得输入流并写入信息到客户端
- class MyServerWriter extends Thread {
- private DataOutputStream dos;
- public MyServerWriter(DataOutputStream dos) {
- this.dos = dos;
- }
- public void run() {
- // 读取键盘输入流
- InputStreamReader isr = new InputStreamReader(System.in);
- // 封装键盘输入流
- BufferedReader br = new BufferedReader(isr);
- String info;
- try {
- while (true) {
- info = br.readLine();
- dos.writeUTF(info);
- if (info.equals("bye")) {
- System.out.println("自己下线,程序退出!");
- System.exit(0);
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
客户端代码:
- package com.basic.socket.client;
- import java.io.BufferedReader;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.net.Socket;
- public class Test_Chat_Client {
- public static void main(String args[]) {
- try {
- // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号
- // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么
- // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection
- // refused: connect
- Socket s1 = new Socket("127.0.0.1", 8888);
- // =========客户端,在这里应该先打开输入流,在打开输出流,
- // =========因为客户端执行的操作是先说,再听,说,听,说,听.....
- // 打开输入流
- InputStream is = s1.getInputStream();
- // 封装输入流
- DataInputStream dis = new DataInputStream(is);
- // 打开输出流
- OutputStream os = s1.getOutputStream();
- // 封装输出流
- DataOutputStream dos = new DataOutputStream(os);
- // 创建并启用两个线程
- new MyClientReader(dis).start();
- new MyClientWriter(dos).start();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- // 接受并打印服务器端传过来的信息
- class MyClientReader extends Thread {
- private DataInputStream dis;
- public MyClientReader(DataInputStream dis) {
- this.dis = dis;
- }
- public void run() {
- String info;
- try {
- while (true) {
- info = dis.readUTF();
- System.out.println("对方说: " + info);
- if (info.equals("bye")) {
- System.out.println("对方下线,程序退出!");
- System.exit(0);
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- // 从键盘获得输入流并写入信息到服务器端
- class MyClientWriter extends Thread {
- private DataOutputStream dos;
- public MyClientWriter(DataOutputStream dos) {
- this.dos = dos;
- }
- public void run() {
- InputStreamReader isr = new InputStreamReader(System.in);
- BufferedReader br = new BufferedReader(isr);
- String info;
- try {
- while (true) {
- info = br.readLine();
- dos.writeUTF(info);
- if (info.equals("bye")) {
- System.out.println("自己下线,程序退出!");
- System.exit(0);
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
客户端运行效果:
- 1 这是客户端
- 2 我是hongten
- 3 这是我说的第三句话,haha
- 4 对方说: 我是服务器端,这说我说的第一句话,hehe
服务器端运行效果:
- 1 对方说: 这是客户端?
- 2 对方说: 我是hongten
- 3 对方说: 这是我说的第三句话,haha
- 4 我是服务器端,这说我说的第一句话,hehe
- java编程_socket_套接字_网络编程
- java编程_socket_套接字_网络编程
- java编程_socket_套接字_网络编程
- 网络编程学习_套接字选项
- Java_网络编程_套接字;
- 网络套接字编程
- [java]网络编程(Socket编程、套接字编程)
- JAVA网络编程 Datagram套接字
- JAVA网络编程 Datagram套接字
- java基础之网络套接字编程
- 【网络编程1】Java套接字Socket
- JAVA021 -- java网络编程之套接字
- Java网络编程-(1)套接字
- java网络编程--socket套接字
- C#网络编程002_套接字解释
- 黑马程序员_网络编程之套接字
- android网络编程_自寻址套接字Data…
- Java编程思想之网络编程(二)套接字Socket
- 黑马程序员_7K面试题之银行调度系统
- 从CVPR2013看计算机视觉研究的三个趋势
- log::Reader-levelDB源码解析
- (unix网络编程)时间获取程序
- log format-levelDB源码解析
- java编程_socket_套接字_网络编程
- 推荐一个背景建模的开源库
- html之api
- ubuntu的apt-get时常用的一些源
- LIOP特征
- C陷阱篇之enum默认长度
- win8 开启网络共享给其他电脑【整理自网上】
- 传递哈希入侵技术
- Python3 BeautifulSoup4结合urllib简单使用