Socket 常用分为以下两种
ServerSocket //服务端
Socket//客户端
简单连接1(服务端):
//创建一个Socket 监听端口为80
ServerSocket serverSocket = new ServerSocket(80);
//获取服务端的Socket
Socket accept = serverSocket.accept();
//创建一个线程专门处理Socket请求
new TestThread(accept).start();
//--------------------TestThread
public static class TestThread extends Thread{
//获取当前服务器Socket
private Socket mSocket;
public TestThread(Socket mSocket){
this.mSocket = mSocket;
}
@Override
public void run() {
try {
//创建一个字符串读取流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
String msg = null;
//如果读取到的东西不为 null 并且不能为空(这是客户端发送过来的消息)
while((msg = bufferedReader.readLine()) != null && !(msg.isEmpty())){
//打印输出看一下
System.out.println(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
//监听 本地 127.0.0.1 端口为80
Socket socket = new Socket("127.0.0.1", 80);
//获取一个打印输出流
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
printWriter.println("我给服务端发送了一个消息");
//刷新流
printWriter.flush();
//关闭流
printWriter.close();
效果图
这个是通过ServletSocket监听一个端口 通过Socket来请求,但是这样你感觉没啥用啊,只能发送一次,链接就被关闭了
没事咋们再来点高端的
简单连接2
服务端不变,来看下客户端
Socket socket = new Socket("127.0.0.1", 80);
new Thread(new Runnable() {
@Override
public void run() {
PrintWriter printWriter = null;
try {
//获取打印输出流
printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
//从键盘获取输入流
Scanner scanner = new Scanner(System.in);
while(true){
String s = scanner.nextLine();
//发送给服务端
printWriter.println(s);
printWriter.flush();
}
}
}).start();
效果图
简单连接 3
你也可以这样,给服务端(Servlet发送时间 1秒发一次 服务端不变)
Socket socket = new Socket("127.0.0.1", 80);
new Thread(new Runnable() {
@Override
public void run() {
PrintWriter printWriter = null;
try {
printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
Date date = new Date();
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// String s = scanner.nextLine();
long l = System.currentTimeMillis();
date.setTime(l);
String format = s.format(date);
printWriter.println(format);
printWriter.flush();
}
}
}).start();
效果图
简单连接 4 (双向通讯)
就是说你收到了服务端的消息,然后你给服务端发送消息,说你收到了
服务端 需要更改一些东西
//创建一个Socket 监听端口为80
ServerSocket serverSocket = new ServerSocket(80);
//获取服务端的Socket
Socket accept = serverSocket.accept();
//创建一个线程专门处理Socket请求
new TestThread(accept).start();
//--------------------TestThread
public static class TestThread extends Thread{
//获取当前服务器Socket
private Socket mSocket;
public TestThread(Socket mSocket){
this.mSocket = mSocket;
}
@Override
public void run() {
try {
//创建一个字符串读取流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
//创建一个打印流,传给客户端
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(mSocket.getOutputStream()),true);
String msg = null;
//如果读取到的东西不为 null 并且不能为空(这是客户端发送过来的消息)
while((msg = bufferedReader.readLine()) != null && !(msg.isEmpty())){
//打印输出看一下
System.out.println(msg);
//发送给客户端
printWriter.println("服务端收到消息:" + msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
Socket socket = new Socket("127.0.0.1", 80);
//多加了一行这个,监听服务端发送过来的消息
new TestThread(socket).start();
new Thread(new Runnable() {
@Override
public void run() {
PrintWriter printWriter = null;
try {
printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
Date date = new Date();
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// String s = scanner.nextLine();
long l = System.currentTimeMillis();
date.setTime(l);
String format = s.format(date);
printWriter.println(format);
printWriter.flush();
}
}
}).start();
//---------------------------------TestThread
public static class TestThread extends Thread {
private Socket mSocket;
public TestThread(Socket mSocket) {
this.mSocket = mSocket;
}
@Override
public void run() {
//基本和服务端写的差不多
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(mSocket.getOutputStream()));
String msg = null;
while ((msg = bufferedReader.readLine()) != null) {
//监听服务端发送过来的消息
System.out.println(msg);
}
printWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
效果图
服务端和客户端都可以双向通讯
服务端 -> 客户端(接收到消息 发送给服务端通知我收到了)->服务端(知道客户端收到消息了 通知给客户端新的东西)->客户端(好的 服务端)->...
连接基本没问题了
你知道Socket还可以这样用吗(http中Socket的应用)
创建一个服务端
服务端(只创建一个服务端就OK,不用写客户端)
try {
//监听80端口
ServerSocket serverSocket = new ServerSocket(80);
Socket accept = serverSocket.accept();
// InputStream inputStream = accept.getInputStream();
new SocketThread(accept).start();
} catch (IOException e) {
e.printStackTrace();
}
//------------------------------SocketThread
public class SocketThread extends Thread {
private Socket mSocket;
public SocketThread(Socket mSocket) {
this.mSocket = mSocket;
}
@Override
public void run() {
try {
//获取一个读取字符串的流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
String msg = null;
//获取一个打印流
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(mSocket.getOutputStream()),true);
StringBuilder stringBuilder = new StringBuilder();
while((msg = bufferedReader.readLine()) != null && !(msg.isEmpty())){
//接收来自浏览器的消息
System.out.println("获取到的消息:" + msg);
//那浏览器的消息加在一起,返回给浏览器
stringBuilder.append(msg + "\n").append("</br>");
}
//给浏览器发送消息
printWriter.println("<!DOCTYPE html>\n" +
"<html>\n" +
"\t<head>\n" +
"\t\t<meta charset=\"GBK\">\n" +
"\t\t<title></title>\n" +
"\t</head>\n" +
"\t<body>\n" + stringBuilder.toString() + "\t</body>\n" +
"</html>\n");
printWriter.flush();
} catch (IOException e) {
e.printStackTrace();
System.out.println("出错了:" + e.toString());
}
}
浏览器传给我们的消息
我们给浏览器传的消息
给浏览器发送消息,也可以想发啥发啥
改这块
我发一个稍微复杂一点的(一个表单)
浏览器的消息
那我是不是可以提交表单啦???
提交不了的,老哥,浏览器请求到一次,请求完直接就关闭连接了,除非你在创建一个ServletSocket监听
老哥现在对Socket的认识是不是感觉有点不一样?(我*Socket竟然能这样用?)
像上边的应用就相当于TCP
说一下UDP
JAVA当中自带了一个UDP的类
UDP这个是我复制来自这个网站的,应为这个玩意不是怎么经常用
这个是服务端,作者都写反了。。。
DatagramSocket ds = null;
DatagramPacket dp = null;
byte[] buf = new byte[1024];
ds = new DatagramSocket(3333);
dp = new DatagramPacket(buf, 1024);
// 接收数据,放入数据报
ds.receive(dp);
// 从数据报中取出数据
String info = new String(dp.getData(),0, dp.getLength());
System.out.println("接收到的信息是:" + info);
}
这个是客户端
public static void main(String[] args) throws Exception {
DatagramSocket ds = null;
DatagramPacket dp = null;
// 构建发送对象
ds = new DatagramSocket();
// 将数据打包-->打成数据报
String info = "hello world!";
dp = new DatagramPacket(info.getBytes(), info.length(), InetAddress.getByName("localhost"),3333);
// 发出数据报
ds.send(dp);
}
----------------------------------------关于Android中Socket的应用
Android中也差不多,只不过用ADB命令映射出来了
adb forward tcp:8888tcp:9999
PC端连接的端口(8888)
Android写的端口(9999)
强行解释一下
adb命令通过映射 PC端(就是你的电脑端)8888端口
映射到Android端9999端口
比如
//这个是我在Android中监听的服务端(服务端和客户端在那个设备上都没问题,服务端在PC上也没问题 是 在Android上也没问题,客户端同理)
ServerSocket serverSocket = new ServerSocket(9999);
...//你的代码
//--------------------------------Android
//这个是我在电脑中监听的客户端 127.0.0.1 是必须写成这个地址,应为是USB连接,所以映射到本机中了
//记住必须写成 127.0.0.1
Socket socket = new Socket("127.0.0.1", 8888);
...//你的代码
Socket 简单的编程讲解完成了,大神们~~~关于Socket实际项目项目当中的应用(比如,我的哥,我这个玩意为什么客户端一断我服务端也断了关闭了-----老哥这个连接只能维持一次,实际项目当中肯定要创建多个Socket 创建一个线程池来维护Socket)
你拉下来也没有Demo
自己动手,理解更加通透(彻底)