点我跳过黑哥的卑鄙广告行为,进入正文。

Java多线程系列更新中~

  正式篇:

  1. Java多线程(一) 什么是线程
  2. Java多线程(二)关于多线程的CPU密集型和IO密集型这件事
  3. Java多线程(三)如何创建线程
  4. Java多线程(四)java中的Sleep方法
  5. Java多线程(五)线程的生命周期

  番外篇(神TM番外篇):

  1. Java 过一下基础
  2. 转载:java中Thread.sleep()函数使用
  3. Java多线程 Socket使用

Socket是客户端和服务器端交流的端点。通过它可以实现客户端和服务器端的通信。顺着这篇文章操作下来,你应该会对Socket编程有比较系统的了解。注意,跟着敲代码,有什么不懂而我又没提到的地方,随时百度,不要积累误差。

客户端编程

Socket是有连接的,所以双方建立通信,需要知道彼此的网络位置(IP和端口)。

创建Socket对象:

Socket socket = new Socket("127.0.0.1",8852);
  • 第一个参数:服务器的IP地址(这里用的是本机地址)
  • 第二个参数:TCP端口号,其中0~1023是系统保留端口。

为什么需要端口号?例如你想要去找你的暗恋对象告白,你知道她的学校地址(IP地址),但是一个学校不会只有你暗恋对象一个人(一个主机不会只进行一个任务),你需要知道她的宿舍号(端口号),这样才能方便告白。

使用本机既做客户端,又做服务器是个什么情况?就是你和你暗恋对象在同一个学校,这没什么区别,你仍然需要她的宿舍号(端口号)才能找到她告白(客户端和服务前通信)。

初始版本代码

public class MyClient {
public static void main(String[] args) throws Exception{
Socket socket = new Socket("127.0.0.1",8852);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF("Hello socket");
socket.close();
}
}

注意别忘了抛出异常,这里只是个演示作用,直接throws Exception了。这里你直接运行肯定是不能建立连接的,因为服务器端还没写。

这里,假如你知道服务器监听的是8852端口,你创建了一个socket来和它进行通信。socket.getOutputStream()得到这个socket的输出流,当你调用writeUTF()方法时,便会向其中写一个字符串。

典型三段式要牢记:打开、通信、关闭。

服务器端编程

注意了注意了,要开始造女票了。

初始版本代码

import java.io.DataInputStream;
import java.net.ServerSocket;
import java.net.Socket; public class MyServer {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(8852);
System.out.println("Server 等待接收数据~");
Socket socket = serverSocket.accept();
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
String string = dataInputStream.readUTF();
System.out.println(string);
System.out.println("Server 接收数据完毕,拜拜了您~");
socket.close();
serverSocket.close();
}
}

这里服务器端用到了ServerSocket,负责接收客户端的连接请求。你的暗恋对象可能有好多人要向她告白,一个Socket自然无法处理。通过ServerSocket的accept方法从连接请求队列中取出一个进行连接。那这个ServerSocket就是你暗恋对象的室友,帮助她管理诸多“告白”。

这里只是把服务器端接收到的数据打印了一下便关闭了。至此,一个简单的服务器-客户端通信便建立了。但是这个服务器只能处理一个连接便关闭了,我们可以改进一下。

往下看之前请确保你大致理解了上述过程,最好自己敲一下代码

到这里你可能会想,只处理一个就关闭了,那我加个while循环,让它一直运行怎么样?

听着还可以,那我们来试验一下(下面只是分析一下,不用跟着敲)。

将服务器端代码更改为:

while(true)
{
  Socket socket = serverSocket.accept();
  DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
  String string = dataInputStream.readUTF();
  System.out.println(string);
  socket.close();
  serverSocket.close();
}

这个会出现什么问题?客户端正连着呢,啪,你服务器给人家断开了,而且accept()接受的是socket请求,所以这种情况,除非客户端再连一次,否则二者的通信就断了。

你可能会说,那我把Socket移到外面呢?

其实吧,这个仔细理一下就会明白,如果放到外面的话,只要你想接收多个socket,就要把

Socket socket = serverSocket.accept();放到while循环中,但是你只要把它放到while循环中,它就只能和一个socket进行通信。这里有兴趣可以再查阅一下资料,下面直接进入线程阶段。

服务器端线程代码

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; public class MyServer { public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(8852);
System.out.println("Server 等待接收数据~");
while(true) {
Socket socket = serverSocket.accept();
       //这里来一个连接请求就让deal去处理,自己在这里等下一个连接请求
deal(socket);
}
} public static void deal(Socket client){
     //这里创建了一个新的线程
new Thread(new Runnable() { @Override
public void run() {
DataInputStream dataInputStream=null;
DataOutputStream dataOutputStream = null;
String receiveFromClient="";
try {
dataInputStream = new DataInputStream(client.getInputStream());
dataOutputStream = new DataOutputStream(client.getOutputStream());
//只是这个线程中一直while循环,不影响其他的线程。
while(true) {
receiveFromClient = dataInputStream.readUTF();
System.out.println("receive: "+receiveFromClient);
if(receiveFromClient.equals("bye"))
{
dataOutputStream.writeUTF("终于厌倦我了吗?客户端都是大猪蹄子!!");
dataOutputStream.flush();
break;
}
else {
dataOutputStream.writeUTF("你TM给我发 "+receiveFromClient+" 干什么?");
dataOutputStream.flush();
}
}
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
dataInputStream.close();
dataOutputStream.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
}).start();
}
}

客户端代码:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket; public class MyClient {
public static void main(String[] args) throws Exception{
Socket socket = new Socket("127.0.0.1",8852);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
String string;
while(true)
{
string=bReader.readLine();
dataOutputStream.writeUTF(string);
System.out.println(dataInputStream.readUTF());
dataOutputStream.flush();
if(string.equals("bye"))
break;
}
socket.close();
}
}

结果展示:

服务器端:

客户端:

Java多线程 Socket使用的更多相关文章

  1. Java多线程Socket在控制台输出的多人聊天室编程

    服务器端代码 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java ...

  2. Java 多线程Socket编程通讯--实现聊天室代码

    1.创建服务器类 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import ja ...

  3. Java 多线程 socket 取款例子 runnable callable

    socket部分参考 http://blog.csdn.net/kongxx/article/details/7259465 取款部分参考 http://blog.csdn.net/dayday198 ...

  4. Java多线程(五)线程的生命周期

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  5. Java多线程(四)java中的Sleep方法

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  6. Java多线程(三)如何创建线程

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  7. Java多线程(一) 什么是线程

    声明:本系列大多是翻译自https://www.javatpoint.com,加上自己的增删改,尽力写的系统而通俗易懂,后文不再重复声明. 点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更 ...

  8. Java多线程(二)关于多线程的CPU密集型和IO密集型这件事

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  9. 简单通过java的socket&serversocket以及多线程技术实现多客户端的数据的传输,并将数据写入hbase中

    业务需求说明,由于公司数据中心处于刚开始部署的阶段,这需要涉及其它部分将数据全部汇总到数据中心,这实现的方式是同上传json文件,通过采用socket&serversocket实现传输. 其中 ...

随机推荐

  1. OpenCV入门之获取图像的旋转角度

      在我们的日常生活中,所碰到的图像往往都有一定的倾斜.那么,如何用OpenCV来获取图像的旋转角度呢?   我们以下面的图片为例,简单介绍如何用OpenCV来获取图像的旋转角度.   可以看到,该图 ...

  2. Core知识整理

    概述 Commond-Line ASP.NET结构文件 Startup 配置文件 中间件和依赖注入 依赖注入原理 框架自带的依赖注入(IServiceCollection) 依赖注入生命周期 依赖注入 ...

  3. element框架中表格的筛选功能使用说明(转载)

    一.element框架中表格的筛选功能使用说明 转载:https://blog.csdn.net/liangxhblog/article/details/80513030 在element ui 框架 ...

  4. [angularjs] angularjs系列笔记(二)指令

    重复HTML元素 ng-repeat指令可以重复HTML元素 <body> <div ng-app="Home" ng-controller="inde ...

  5. eclipse下svn的使用

    描述:本篇用解决下面的案例中的问题来描述eclipse svn插件的使用. a.案例 某研发团队开发了一款名为App,目前已发布v1.0版本.此项目初期已有部分基础代码, 研发团队再此基础代码上经过3 ...

  6. js高级:event,事件冒泡,事件捕获

    1.事件 浏览器客户端上客户触发的行为都称为事件 所有的事件都是天生自带的,不需要我们去绑定,只需要我们去触发. 通过 obj.事件名=function(){} 事件名:onmouseover 鼠标悬 ...

  7. 创建Aurelia项目

    什么是Aurelia? Aurelia 是一个新的开源的,基于web标准的mvvm框架,是一个现代化的js模块的集合. Aurelia提供了丰富的plugin,例如国际化,验证,模态框,UI可视化等. ...

  8. 反向ajax实现原理

    留言板显示留言一直刷新,那么实现原理是怎么样的? 一般发送留言就是通过正常的ajax向服务器发送数据,而实时显示留言就需要用到轮询了. 什么是轮询:就是使用定时器,每隔固定的时间从客户端向服务器发起请 ...

  9. 洛谷P4170 [CQOI2007]涂色(区间dp)

    题意 题目链接 Sol 震惊,某知名竞赛网站竟照搬省选原题! 裸的区间dp,\(f[l][r]\)表示干掉\([l, r]\)的最小花费,昨天写的时候比较困于是就把能想到的转移都写了.. // luo ...

  10. SAP MM 物料主数据MRP2 视图’Minimum Lot Size’字段

    SAP MM 物料主数据MRP2 视图’Minimum Lot Size’字段 如下物料号,MRP2视图中,维护了最小采购量为500. MRP type : PD Lot size: EX Minim ...