- UID
- 153568
- 阅读权限
- 50
- 注册时间
- 2017-8-19
- 最后登录
- 1970-1-1
- 在线时间
- 小时
- 人气
- 点
- MC币
- 个
- 贡献
- 点
TA的每日心情 | 开心 2022-12-10 07:47 |
---|
签到天数: 26 天 [LV.4]偶尔看看III
|
本帖最后由 Prismaillya 于 2017-9-2 18:38 编辑
Socket实现简单发送消息
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
Socket和ServerSocket类库位于java.net包中。
ServerSocket用于服务器端,Socket是建立网络连接时使用的。
在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。
对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。
不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
下面的代码演示的是客户端向服务端发送数据,支持发送多条消息,但是只能单向发送消息,有点类似于我学校电脑室的学生机被控端软件的“发送消息给教师”的功能。
客户端代码 (Client.java):
package com.prismaillya.tcp;
import java.io.*;
import java.net.*;
public class Client { /**
* 程序主类,创建Socket并连接至指定服务器
**/
public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1", 5785); //服务器IP地址,端口
DataInputStream is = new DataInputStream(s.getInputStream()); //创建数据输入流
DataOutputStream os = new DataOutputStream(s.getOutputStream()); //创建数据输出流
System.out.println("Input your message here: "); //打印提示字符
String outStr, inStr;
boolean NotExit = true;
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in)); //创建缓冲方式读取
while (NotExit) {
outStr = buf.readLine(); //从输入流中读取数据
os.writeUTF(outStr); //向服务器发送数据
os.flush(); //清空缓冲区数据
inStr = is.readUTF(); //读取输入流即服务器返回的结果
if (!inStr.equals("exit")) { //如果消息内容不是“exit”
System.out.println("Server Return: " + inStr); //打印服务器返回消息
} else {
NotExit = false; //跳出循环
System.out.println("Server Return: " + inStr + " and close the connection."); //打印断开连接消息
}
}
is.close(); //关闭输入流
os.close(); //关闭输出流
s.close(); //关闭socket
} catch (ConnectException ex) {
System.err.println("Failed to connect to server, connect refused."); //连接失败时打印错误信息
} catch (SocketException es) {
System.err.println("Failed to send message, connect reset."); //连接被重置时打印错误信息
} catch (IOException e) {
System.err.println(e); //发生IO错误时打印错误信息
}
}
}
服务端代码 (MultiServer.java):
package com.prismaillya;
import java.io.*;
import java.net.*;
public class MultiServer {
/**
* 服务器主类,负责启动服务器线程
**/
public static void main(String[] args) throws IOException {
System.out.println("Wait for connect......");
ServerSocket serverSocket = new ServerSocket(5785); //创建Socket,5785 是你要绑定的端口,需要和客户端相同
Socket s = null;
while (true) {
s = serverSocket.accept(); //开始接受客户端请求
ServerThread serverThread = new ServerThread(s); //创建服务器线程
}
}
}
服务端核心代码(ServerThread.java):
package com.prismaillya;
import java.io.*;
import java.net.*;
public class ServerThread extends Thread {
private final Socket s;
private final DataInputStream is;
private final DataOutputStream os;
public ServerThread(Socket socket) throws IOException {
super(); //调用父类构造函数
s = socket;
is = new DataInputStream(s.getInputStream()); //创建数据输入流
os = new DataOutputStream(s.getOutputStream()); //创建数据输出流
start(); //启动线程
}
@Override
public void run() {
try {
String message; //客户端发送的消息
boolean NotExit = true; //阻止连接断开
while (NotExit) {
message = is.readUTF(); //从数据输入流读取客户端发送的数据
if (!message.equals("exit")) { //如果消息内容不是“exit”
System.out.println("Client send message: " + message); //打印客户端发送的消息
os.writeUTF("You Send: " + message); //向客户端返回数据
os.flush(); //清空缓冲区
} else {
NotExit = false; //如果客户端发送了“exit”,则跳出循环
os.writeUTF("exit"); //向客户端返回“exit”,即告诉客户端断开连接。
os.flush(); //清空缓冲区
System.out.println("Client disconnect."); //打印客户端断开连接的消息
}
}
is.close(); //关闭数据输入流
os.close(); //关闭数据输出流
s.close(); //关闭Socket
} catch (SocketException ex) {
System.err.println("Connect reset."); //连接被重置时打印错误消息
} catch (IOException e) {
System.err.println(e); //发生IO错误时打印错误消息
}
}
}
PS:论坛不支持代码高亮,但是我还是手动语法高亮了......真的累啊!!
这是非常简单的一个 Socket 发送消息的例子,也是当时我学习Java的时候做的一个简易聊天软件,对新人学习 Socket 很有帮助,如果有什么不明白的地方也可以来问我。
|
|