要想详细了解socket,大家请自行百度,我这里只简单介绍。

  在网络中,我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程。而socket编程就是为了完成两个唯一进程之间的通信(一个是客户端,一个是服务器端),其中用到的协议是TCP/UDP协议,它们都属于传输层的协议。

  TCP是基于连接的协议,在收发数据前,需要建立可靠的连接,也就是所谓的三次握手。使用TCP协议时,数据会准确到达,但是效率较低。

  UDP是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去。使用UDP协议时,传输效率高,但是不能保证数据准确到达,视频聊天,语音聊天时就用的UDP协议。

  以使用TCP协议通讯的socket为例,其交互流程大概是这样子的:

              服务器端              客户端

           创建服务器端的socket        创建客户端的socket

           绑定端口号             连接服务器端的端口

           监听端口              向服务器端发送数据

           接收客户端的连接请求        关闭socket

           读取客户端发送数据

           关闭socket

  下面贴上代码:

  服务器端:

package SocketStudy;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket; public class SocketServer {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(10068);//创建绑定到特定端口的服务器Socket。
Socket socket = null;//需要接收的客户端Socket
int count = 0;//记录客户端数量
System.out.println("服务器启动");
//定义一个死循环,不停的接收客户端连接
while (true) {
socket = serverSocket.accept();//侦听并接受到此套接字的连接
InetAddress inetAddress=socket.getInetAddress();//获取客户端的连接
ServerThread thread=new ServerThread(socket,inetAddress);//自己创建的线程类
thread.start();//启动线程
count++;//如果正确建立连接
System.out.println("客户端数量:" + count);//打印客户端数量
}
} catch (IOException e) {
e.printStackTrace();
} }
}

 自定义线程类:

package SocketStudy;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket; public class ServerThread extends Thread {
Socket socket = null;
InetAddress inetAddress=null;//接收客户端的连接 public ServerThread(Socket socket,InetAddress inetAddress) {
this.socket = socket;
this.inetAddress=inetAddress;
} @Override
public void run() {
InputStream inputStream = null;//字节输入流
InputStreamReader inputStreamReader = null;//将一个字节流中的字节解码成字符
BufferedReader bufferedReader = null;//为输入流添加缓冲
OutputStream outputStream = null;//字节输出流
OutputStreamWriter writer = null;//将写入的字符编码成字节后写入一个字节流
try {
inputStream = socket.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
bufferedReader = new BufferedReader(inputStreamReader);
String info = null;//临时 //循环读取客户端信息
while ((info = bufferedReader.readLine()) != null) {
//获取客户端的ip地址及发送数据
System.out.println("服务器端接收:"+"{'from_client':'"+socket.getInetAddress().getHostAddress()+"','data':'"+info+"'}");
} socket.shutdownInput();//关闭输入流 //响应客户端请求
outputStream = socket.getOutputStream();
writer = new OutputStreamWriter(outputStream, "UTF-8");
writer.write("{'to_client':'"+inetAddress.getHostAddress()+"','data':'我是服务器数据'}");
writer.flush();//清空缓冲区数据
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
try {
if (writer != null) {
writer.close();
}
if (outputStream != null) {
outputStream.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (inputStream != null) {
inputStream.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} }
}

客户端:

package SocketStudy;

import java.io.*;
import java.net.Socket;
import java.util.Scanner; public class SocketClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("服务器的ip", 10068);
OutputStream outputStream = socket.getOutputStream();//得到一个输出流,用于向服务器发送数据
OutputStreamWriter writer=new OutputStreamWriter(outputStream,"UTF-8");//将写入的字符编码成字节后写入一个字节流
System.out.println("请输入数据:");
Scanner sc = new Scanner(System.in);
String data = sc.nextLine();
writer.write(data);
writer.flush();//刷新缓冲
socket.shutdownOutput();//只关闭输出流而不关闭连接
//获取服务器端的响应数据 InputStream inputStream = socket.getInputStream();//得到一个输入流,用于接收服务器响应的数据
InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"UTF-8");//将一个字节流中的字节解码成字符
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);//为输入流添加缓冲
String info = null;        System.out.println("客户端IP地址:"+socket.getInetAddress().getHostAddress());
            //输出服务器端响应数据
while ((info = bufferedReader.readLine()) != null) {
System.out.println("客户端接收:" + info);
}
//关闭资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
writer.close();
outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

运行结果(先运行服务器端,再运行客户端):

服务器:

客户端:

回车之后

客户端:

服务器端:

在cmd下运行(先编译再运行生成的.class文件,如果有中文,需要加encoding参数,当类中有导入自己创建的类时,需要切换到能包含该类的文件夹下执行命令,否则会报错)

此时的服务器端:

  

Java使用多线程实现Socket多客户端的通信的更多相关文章

  1. 《Unity 3D游戏客户端基础框架》多线程异步 Socket 框架构建

    引言: 之前写过一个 demo 案例大致讲解了 Socket 通信的过程,并和自建的服务器完成连接和简单的数据通信,详细的内容可以查看 Unity3D -- Socket通信(C#).但是在实际项目应 ...

  2. 利用多线程使socket服务端可以与多个客户端同时通讯

    利用多线程使socket服务端可以与多个客户端同时通讯 server import socket 1. 符合TCP协议的手机 server = socket.socket(socket.AF_INET ...

  3. 编写Java程序,使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的场景(用户充当客户端,QQ 小冰充当服务端)

    查看本章节 查看作业目录 需求说明: 小冰是微软公司研发的人工智能机器人,被腾讯公司加入 QQ 群后,立即受到千万网友的喜爱.现在使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的 ...

  4. 【关于java多线程和socket通信的一些记录】---高并发/高负载/高可用/重入锁

    多线程:提高cpu的使用效率,多线程是指在同一程序中有多个顺序流在执行. 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线 ...

  5. Python拾忆--多线程的socket服务器

    阳光明媚的午后,想想最近要开始从写Java到写Python了,就随手打开电脑来体验一下Python与Java之间的不同吧~ 记得我还在上大二的时候,那个时候才开始学Java,最感兴趣的就是Java书最 ...

  6. 8.多线程和Socket通信

    一.多线程 1.进程的概念: 进程就是应用程序的执行实例,有独立的内存空间和系统资源.当一个应用程序没有执行的时候,它就不是一个进程.   2.进行的特征: (1)动态性:动态产生动态消亡. (2)并 ...

  7. 多线程服务端与客户端通信(IO是阻塞的)_02

    下面是多线程的;每次服务端接受请求,会创建一个线程专门处理这个请求: 虽然是多线程的,但还是阻塞,相当于单线程处理模式 public class TimeServer { public static ...

  8. java基础-多线程应用案例展示

    java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...

  9. Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制

    Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...

随机推荐

  1. java indexOf 和 split的用法

    1.java 的 indexOf 方法 ,如果存在 则 指定的字符串的开始位置,如果不存在 则返回-1: 2.java 的 split的方法:将一个字符串分割为子字符串,然后将结果作为字符串数组返回. ...

  2. Django 简单教程(入门级)

    一.Django简介 1. web框架介绍 具体介绍Django之前,必须先介绍WEB框架等概念. web框架: 别人已经设定好的一个web网站模板,你学习它的规则,然后“填空”或“修改”成你自己需要 ...

  3. CentOS随笔 - 修改CentOS7的IP

    前言 转帖请注明出处: http://www.cnblogs.com/Troy-Lv5/ 在使用CentOS时经常我们需要固定一个IP, 因为服务器嘛,不固定IP. 难道每次都要配置开发环境的地址.? ...

  4. [翻译] LTInfiniteScrollView

    LTInfiniteScrollView 效果: Usage - 使用 Create the scroll view by: 通过以下方式来创建出scroll view self.scrollView ...

  5. css动画 文字闪烁效果

    /*定义页面基础CSS*/ body{ font-family: 'microsoft yahei',Arial,sans-serif; color: #EFEFEF; background: #22 ...

  6. 音乐MP4网站 车辆工程 冯大昕

  7. Mysql常用的锁机制

    一.引言                                                                                                 ...

  8. MapReduce Design Patterns(chapter 1)(一)

    Chapter 1.Design Patterns and MapReduce MapReduce 是一种运行于成百上千台机器上的处理数据的框架,目前被google,Hadoop等多家公司或社区广泛使 ...

  9. openresty及lua的随机函数

    我们都知道,所谓的随机都是伪随机,随机的结果是由随机算法和随机种子决定的. 所以,当我们没有初始化的时候,如果直接使用math.random(),那么出来的值肯定是每次都一样,因为种子等于0. 因此, ...

  10. Linq to Entities,ADO.NET Entity Framework 模型优先

    一.概念: Database First(数据库优先):存在的DB------------->生成Data Model  .edmx文件 Model First(模型优先):Data Model ...