1:Socket与ServerSocket的交互

2.Socket和ServerSocket介绍

Socket

构造函数

Socket()

Socket(InetAddress address, int port)throws UnknownHostException, IOException

Socket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException

Socket(String host, int port)throws UnknownHostException, IOException(最简单的连接方式)

Socket(String host, int port, InetAddress localAddress, int localPort)throws IOException

除去第一种不带参数的之外,其它构造函数会尝试建立与服务器的连接。如果失败会抛出IOException错误。如果成功,则返回Socket对象。

InetAddress是一个用于记录主机的类,其静态getHostByName(String msg)可以返回一个实例,其静态方法getLocalHost()也可以获得当前主机的IP地址,并返回一个实例。

Socket(String host, int port, InetAddress localAddress, int localPort)构造函数的参数分别为目标IP、目标端口、绑定本地IP、绑定本地端口。

Socket方法

getInetAddress();    远程服务端的IP地址

getPort();    远程服务端的端口

getLocalAddress()    本地客户端的IP地址

getLocalPort()    本地客户端的端口

getInputStream();    获得输入流

getOutStream();    获得输出流

值得注意的是,在这些方法里面,最重要的就是getInputStream()和getOutputStream()了。

Socket状态

isClosed();     //连接是否已关闭,若关闭,返回true;否则返回false

isConnect();      //如果曾经连接过,返回true;否则返回false

isBound();     //如果Socket已经与本地一个端口绑定,返回true;否则返回false

ServerSocket

构造函数

ServerSocket()throws IOException

ServerSocket(int port)throws IOException

ServerSocket(int port, int backlog)throws IOException

ServerSocket(int port, int backlog, InetAddress bindAddr)throws IOException

注意点:

1. port服务端要监听的端口;backlog客户端连接请求的队列长度;bindAddr服务端绑定IP

2. 如果端口被占用或者没有权限使用某些端口会抛出BindException错误。譬如1~1023的端口需要管理员才拥有权限绑定。

3. 如果设置端口为0,则系统会自动为其分配一个端口;

4. bindAddr用于绑定服务器IP,为什么会有这样的设置呢,譬如有些机器有多个网卡。

5. ServerSocket一旦绑定了监听端口,就无法更改。ServerSocket()可以实现在绑定端口前设置其他的参数。

3.实例前说明

Socket网络编程主要用于两台机器之间的数据传输,大致过程为:建立连接→信息传递→关闭连接。我们可以理解为服务器(ServerSocket)和客户端(Socket),服务器提供连接服务,客户端链接服务器。因为服务器需要向多台客户端提供服务,所以需要一直保持监听状态,不断地监听客户端请求,在这个过程中,ServerSocket一直处于阻断状态,直到有客户端连接,马上返回一个Socket对象,然后通过IO流传输数据,在这个过程中,当有数据传输的时候,IO流才被激活,其余时间都处于阻断状态,等待数据发送过来,然后进行处理。

注意:

当我们发送数据的时候,必须使用flush()方法,将数据提交,否则只会存在于缓冲中,不会发送数据,有时候即使我们使用flush()方法,也无法从另一台电脑上读取到数据,这是因为Socket会将数据先存储起来,等到数据量达到一定大小的时候,会一起提交(或者这样理解,flush()会根据换行符’\n’判断用户是否完成输入,如果没有看到’\n’,Socket认为用户数据还没有写完,仍在保留在缓存池中)所以我们可以在要提交的数据加上’\n’强制提交就可以了。

不过,如果我们没必要很多的交互,只需要交互一次就可以了,就可以不在乎这些,当关闭Socket的输入输出流的时候,Socket会将缓存池中的数据全部提交到另一台机器。

最后最重要的,当我们用完流的时候,一定要及时关闭,养成良好的习惯。

在下面的实例中,我通过多线程的方式保证服务器和客户端一直处于数据交互状态,并且使用线程池的方式维护线程。、

线程类:

package com.best.alivn.socketservice;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;/**让服务器处理与客户端通讯放在线程中* Created by Alivn on 2017/3/18.*/
public class SessionThread  implements Runnable{private final Socket client;private static Integer Tag=0;public SessionThread(Socket client) {this.client = client;}@Overridepublic void run() {//输出流PrintWriter writer=null;//获取客户端输入流,得到客户端发来的消息try {//读取客户端的数据//读取到的一行数据String line=null;//客户端发来的数据//开启一个读线程Thread write_thread= new Thread(new Runnable() {@Overridepublic void run() {//输入流InputStream inputStream=null;BufferedReader reader=null;try {while (true) {inputStream= client.getInputStream();//为了提高效率,转换成字符流reader=new BufferedReader(new InputStreamReader(inputStream));String line=null;while ((line=reader.readLine())!=null){System.out.println(line);}}} catch (IOException e) {//流异常
                        e.printStackTrace();}finally {//关闭流try {inputStream.close();reader.close();} catch (IOException e) {e.printStackTrace();}}}});write_thread.start();//获取输出流,往客户端发送数据writer=new PrintWriter(client.getOutputStream());//客户端刚连接的时候,客户端反馈信息String send_msg ="您已成功连接到服务器......--[Server]";writer.println(send_msg);writer.flush();//可以多次发送//从键盘输入while ("1".equals("1")) {Scanner scanner=new Scanner(System.in);send_msg =scanner.nextLine()+"--[Server]";writer.println(send_msg);//注意(我们发送数据的时候,flush方法会提交我们的数据,但是还不会发送,当数据达到一定容量才会发送,// 或者读到换行符的时候发送)
                writer.flush();}} catch (IOException e) {//获取客户端输入流失败
            e.printStackTrace();}finally {//关闭流try {client.shutdownInput();client.shutdownOutput();writer.close();} catch (IOException e) {//关闭输入输出流失败
                e.printStackTrace();}}}
}

服务器类:

package com.best.alivn.socketservice;
import scala.actors.threadpool.ExecutorService;
import scala.actors.threadpool.Executors;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;/**服务器* Created by Alivn on 2017/3/18.*/
public class Server {//甚至端口号private  final static Integer PORT=8888;//设置开启的线程数private  final  static  Integer THREAD_SIZE=5;//创建线程池private  static  ExecutorService executorService=null;public static void main(String[]args){executorService  = Executors.newFixedThreadPool(THREAD_SIZE);//创建服务器套接字try {//创建三个线程放入到线程池中....ServerSocket serverSocket=new ServerSocket(PORT);//开启服务器,一直处于监听的状态System.out.println("[Server]:服务器已启动.........");while (true){//服务器根据端口号,监听客户端链接,Socket client = serverSocket.accept();System.out.println("[Server]:有客户端链接至服务器.......");//将交互放到线程中SessionThread session=new SessionThread(client);//放入到线程池中
                session.run();executorService.execute(session);}} catch (IOException e) {//实例化服务器失败
            e.printStackTrace();}}}

客户端类:

package com.best.alivn.socketservice;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;/**客户端* Created by Alivn on 2017/3/18.*/
public class Client {private final  static  String host="localhost";private final  static  Integer port=8888;public  static  void main(String[] args)  {Socket socket=null;//输入流BufferedReader reader=null;//创建客户端对象try {//连接服务器socket=new Socket(host,port);//客户端刚连接的时候,客户端反馈信息//输出流final PrintWriter writer=new PrintWriter(socket.getOutputStream());;String  send_msg ="你好,我是小白......--[Client]";writer.println(send_msg);writer.flush();//开启一个线程,处理循环Thread write_Stream=  new Thread(new Runnable() {@Overridepublic void run() {//循环输入数据Scanner scanner=new Scanner(System.in);while ("1".equals("1")){String send_msg=scanner.nextLine()+"--[Client]";writer.println(send_msg);writer.flush();}}});write_Stream.start();while ("1".equals("1")) {//获取输入流,得服务端的数据reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));String line=null;while ((line=reader.readLine())!=null){System.out.println(line);}}writer.close();} catch (IOException e) {//链接失败   文件读取失败
            e.printStackTrace();}finally {//关闭流try {reader.close();socket.shutdownInput();socket.shutdownOutput();} catch (IOException e) {e.printStackTrace();}}}
}

转载于:https://www.cnblogs.com/ljp-sun/p/6576720.html

在Java中使用Socket模拟客户端和服务端(多线程)相关推荐

  1. Java中利用socket实现简单的服务端与客户端的通信(中级)——实现任意双向通信

    本文计划采用socket实现客户端和服务端的任意双向通信,即客户端可以随时给服务端发消息,服务端也可以随时给客户端发消息,最终结果就是一个类似与QQ的聊天软件的功能. 以下代码可以直接拷贝到Eclip ...

  2. Java中利用socket实现简单的服务端与客户端的通信(基础级)

    在上一篇文章中,简单的介绍了java中入门级的socket编程,简单的实现了客户端像服务器端发送数据,服务器端将数据接收并显示在控制台,没有涉及多线程.上一篇文章的链接:Java中利用socket实现 ...

  3. java网络编程Socket实现客户端向服务端发送信息

    (可按目录按需阅读,我一般会整理的比较细) 前置知识 java IO Socket 什么是socket?socket字面意思其实就是一个插口或者套接字,包含了源ip地址.源端口.目的ip地址和源端口. ...

  4. Java中利用socket实现简单的服务端与客户端的通信(入门级)

    Java编程中,要想要使用网络通信,就离不开Socket编程,在此对socket进行简单的介绍.首先声明,这是一个入门级的介绍,仅仅简单的实现了客户端向服务端发送数据,服务端正常的接收数据,当接收到特 ...

  5. gPRC简介以及Java中使用gPRC实现客户端与服务端通信(附代码下载)

    场景 ProtoBuf的介绍以及在Java中使用protobuf将对象进行序列化与反序列化: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/det ...

  6. socket模拟客户端和服务端

    思路:客户端先接收键盘的数据,变为输出流再转化为打印流,安行发送,接收来自服务端的数据,按行读取,最后关闭输入输出,释放资源 服务端按行接收数据,进行处理,变为输出流再转化为打印流,安行发送,最后关闭 ...

  7. php winform通信,C# Winform 通过Socket实现客户端和服务端TCP通信

    操作界面如下: 1.声明Socket 第一个参数:寻址方式,第二个参数:传输数据的方式,第三个参数:通信协议 Socket socket = new Socket(AddressFamily.Inte ...

  8. Java中Socket实现客户端和服务端通信(多线程实现全双工通信)

    效果图 目录结构 服务端Server package server;import thread.SocketReader; import thread.SocketWrite;import java. ...

  9. 基于Socket实现客户端与服务端通讯

    基于Socket实现客户端与服务端通讯 socket 概述 Socket,套接字就是两台主机之间逻辑连接的端点.TCP/IP协议是传输层协议,主要解决数据如何 在网络中传输,而HTTP是应用层协议,主 ...

最新文章

  1. c# 持续集成 单元测试_如何在不进行单元测试的情况下设置持续集成
  2. 解决js中数字相减为负数的情况
  3. 跨界 | 隐形AI与设计
  4. 怎么把数字替换成空格_Excel中带单位后缀的数字如何计算?
  5. 尽快卸载这两款恶意浏览器插件!已有近50万用户安装
  6. MySQL通过两表避免回表_mysql利用覆盖索引避免回表优化查询
  7. c调用按钮点击事件_React中事件的写法总结
  8. 机器学习基础-支持向量机 SVM-17
  9. windows下连接smb服务器
  10. 服务器是什么系统_服务器自愈路由系统、单线以及BGP多线的区别是什么?
  11. linux下c和c++互相调用
  12. html 按钮光束,图文详解,原来3dmax光束特效的制作这么简单!
  13. Python3网络爬虫开发实战,Appium+mitmdump 爬取京东商品
  14. 自己构造公共程序(3)--DataGrid小方法
  15. MySQL数据库所有知识点最详细讲解,内置官方文档、个人理解、代码演示,自学MySQL必备文档(一)
  16. 用npm安装yarn
  17. 三星s8html查看器,三星S8应用提取|亲测S7可用 - 可直接安装
  18. DSP CCS12.00 芯片:TMS320F28335 结课设计 数字电压表 TFTLCD 模块 + ADC 模块
  19. Java SE核心I
  20. matlab中有没有谱聚类,matlab – 谱聚类

热门文章

  1. 怎么在windows安装python模块_如何在windows环境下安装python里的模块
  2. WH-G405tf连接公网服务器进行透传
  3. Django的学习需要掌握的一些基础和初步搭建自己的框架
  4. Nginx在windows上安装 及 Nginx的配置及优化
  5. 两个排序数组的中位数(4.Median of Two Sorted Arrays)
  6. 550 Ip frequency limited
  7. find指定具体时间参数-newermt
  8. Git005--工作区和暂存区
  9. [Usaco2007 Oct] Super Paintball超级弹珠
  10. 找出没有相邻的1的二进制数的个数---2013年2月17日