java的Socket


java API为我们网络通信提供了服务器套接字ServerSocket类和客户端套接字Socket,Socket是网络驱动层提供给应用程序编程的接口和一种机制。

下面提供具体实现例子

服务端--ServerSocket

ServerSocket类实现了服务器的套接字,主要方法

ServerSocket(int port)-----创建绑定到特定端口的服务器套接字

void setSoTimeout(timeout);----指定超时时间

InetAdress getInetAddress()----返回此服务器套接字的本机地址

Socket accept()--------------侦听并接受此套接字的连接

示例代码:

  1. package com;
  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.IOException;
  5. import java.net.ServerSocket;
  6. import java.net.Socket;
  7. public class Test {
  8. public static void main(String[] args) {
  9. try {
  10. ServerSocket server=new ServerSocket(8080);
  11. //等待客户端连接
  12. while(true){
  13. Socket client=server.accept();
  14. //每个客户端建立一个线程
  15. new Thread(new myRunnable(client)).start();;
  16. }
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }
  22. class myRunnable implements Runnable{
  23. private Socket socket;
  24. public myRunnable(Socket s)
  25. {
  26. this.socket=s;
  27. }
  28. //----run方法运行完毕,线程正常结束
  29. @Override
  30. public void run() {
  31. try {
  32. //接收客户端数据
  33. BufferedInputStream is=new BufferedInputStream(socket.getInputStream());
  34. int data=is.read()+1;//把客户的数据加一
  35. Thread.sleep(1000);//休眠一秒
  36. //输出到客户端
  37. BufferedOutputStream os=new BufferedOutputStream(socket.getOutputStream());
  38. os.write(data);//返回数据给客户端
  39. os.close();
  40. os.close();
  41. } catch (IOException | InterruptedException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }

复制代码

客户端----Socket

Socket类实现客户端套接字,套接字是两台机器间通信的端点,主要方法有

Socket(String host,int port)----创建一个套接字将其连接到指定主机的指定端口号

InputStream getInputStream()----返回此套接字的输入流

OutputStream getOutputStream()----返回此套接字的输出流

示例代码:

  1. package com;
  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.IOException;
  5. import java.net.Socket;
  6. import java.net.UnknownHostException;
  7. public class Client {
  8. public static void main(String[] args) {
  9. for(int i=0;i<20;i++)
  10. {
  11. try {
  12. Socket socket = new Socket("localhost", 8080);
  13. //输出到服务器
  14. BufferedOutputStream os=new BufferedOutputStream(socket.getOutputStream());
  15. os.write(i);
  16. os.flush();
  17. //os.close();不能再这里关闭流,关闭流会导致socket也关闭
  18. // 构建字符缓冲流
  19. BufferedInputStream is=new BufferedInputStream(socket.getInputStream());
  20. int data=is.read();
  21. is.close();
  22. os.close();
  23. System.out.println(data);
  24. } catch (UnknownHostException e) {
  25. e.printStackTrace();
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }
  31. }

复制代码

主要不能提前关闭输入输出流,关闭输入输出流会导致Socket关闭

可以引起网络连接关闭的情况有以下4种:

1.直接调用Socket类的close方法。

2.只要Socket类的InputStream和OutputStream有一个关闭,网络连接自动关闭(必须通过调用InputStream和OutputStream的 close方法关闭流,才能使网络可爱接自动关闭)。

3.在程序退出时网络连接自动关闭。

4.将Socket对象设为null或未关闭最使用new Socket(…)建立新对象后,由JVM的垃圾回收器回收为Socket对象分配的内存空间后自动关闭网络连接。

线程池

在处理多个客户端时是为每一个连接创建一个线程,然而频繁的线程创建会影响性能,所以我们可以使用线程池来解决频线程的创建问题。

线程池:线程池是一种预先创建线程的一种技术。线程池在任务还没到来之前,创建一定数量的线程,放到空闲队列,然后对这些资源进行复用,减少频繁的线程创建和销毁。

JDK1.5版本后提供了线程池,线程池的顶级接口是Executor,是一个执行工具,线程池的直接接口是ExecutorService,是并发开发中常用的工具类

要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。

1. newSingleThreadExecutor

创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

2. newFixedThreadPool

创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

3. newCachedThreadPool

创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,

那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

4. newScheduledThreadPool

创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

此时我们在服务器的用上线程池,使用newFixedThreadPool,代码改为

Java代码  [url=][/url]

  1. package com;

  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.IOException;
  5. import java.net.ServerSocket;
  6. import java.net.Socket;
  7. import java.util.concurrent.ExecutorService;
  8. import java.util.concurrent.Executors;
  9. public class Test {
  10. public static void main(String[] args) {
  11. try {
  12. ServerSocket server=new ServerSocket(8080);
  13. //获取cpu数
  14. int cpu_Num=Runtime.getRuntime().availableProcessors();
  15. //创建指定大小的线程池
  16. ExecutorService es=Executors.newFixedThreadPool(cpu_Num);
  17. //等待客户端连接
  18. while(true){
  19. Socket client=server.accept();
  20. //每个客户端建立一个线程
  21. //new Thread(new myRunnable(client)).start();
  22. es.execute(new myRunnable(client));
  23. }
  24. } catch (IOException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. }
  29. class myRunnable implements Runnable{
  30. private Socket socket;
  31. public myRunnable(Socket s)
  32. {
  33. this.socket=s;
  34. }
  35. //----run方法运行完毕,线程正常结束
  36. @Override
  37. public void run() {
  38. try {
  39. //接收客户端数据
  40. BufferedInputStream is=new BufferedInputStream(socket.getInputStream());
  41. int data=is.read()+1;//把客户的数据加一
  42. Thread.sleep(1000);//休眠一秒
  43. //输出到客户端
  44. BufferedOutputStream os=new BufferedOutputStream(socket.getOutputStream());
  45. os.write(data);//返回数据给客户端
  46. os.close();
  47. os.close();
  48. } catch (IOException | InterruptedException e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. }

复制代码

这样虽然现实了并发服务器,但这样的服务器效率低,吞吐量低,想提高服务器性能,可以研究学习java的nio和aio,能大大提升服务器性能。

时间: 2024-08-27 06:31:23

java的Socket的相关文章

Java基于Socket文件传输示例(转)

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度.废话少说,先来看服务器端的程序. 1.服务器端 package sterning; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream;

java.net.ServerSocket和java.net.Socket

个人博客地址:http://www.cnblogs.com/wdfwolf3/ java.net.ServerSocket 1.构造函数 a.ServerSocket() 创建一个无连接的server socket. b.ServerSocket(int port) 绑定到port端口上 c.ServerSocket(int port, int backlog) backlog表示等待连接的队列最大长度 d.ServerSocket(int port, int backlog, InetAddr

java网络socket编程详解

7.2 面向套接字编程    我们已经通过了解Socket的接口,知其所以然,下面我们就将通过具体的案例,来熟悉Socket的具体工作方式 7.2.1使用套接字实现基于TCP协议的服务器和客户机程序    依据TCP协议,在C/S架构的通讯过程中,客户端和服务器的Socket动作如下: 客户端: 1.用服务器的IP地址和端口号实例化Socket对象. 2.调用connect方法,连接到服务器上. 3.将发送到服务器的IO流填充到IO对象里,比如BufferedReader/PrintWriter

Java Secure Socket Extension (JSSE) Reference Guide

Skip to Content Oracle Technology Network Software Downloads Documentation Search Java Secure Socket Extension (JSSE) Reference Guide This guide covers the following topics: Skip Navigation Links Introduction Features and Benefits JSSE Standard API S

Java通过socket实现smtp协议发送邮件

import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;import java.net.UnknownHostException; import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; /** 

java,Socket,NIO随笔记录

这个答案答的很好.Socket与SocketChannel是俩套api而已,对于网络tcp通信而言不会关心你上层是用何api实现通信的.所以答案是肯定的.SocketChannel可以设置为非阻塞的,所以在某种情况下性能更好,线程不会被挂住.SocketChannel还能注册selector和感兴趣的事件.selector多路复用器这里就不多做介绍了. 在这里介绍一下通信过程中数据的流动过程.首先当数据被网卡接收后,会被保存到内核中,电脑进行拆包解析,看源端口号,会将此数据包保存到对应链接的tc

java下socket传图片

package cn.stat.p4.ipdemo; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class imageserver { /**

基于java的socket编程

#开头的废话#学习java已经半个月了,原本在抠教材里面的字眼时,觉得教材好厚,要看完不知道要到猴年马月去了.突然在网上看到一个教程,里面老师说学编程语言书不用太细看,看个大概,知道里面讲些什么就好,不用全记得,然后你一个劲地编,使劲地编,编的时候不懂再回来看就好了,这是最快的方法.心里一琢磨,还真是这样,根据以前学C语言的情况不就这样吗.所以便加速看,把一些书里介绍的方法,类飞速地浏览过了,刷到网络这一章,觉得socket编程应该是得试一下手,不要只看不做假把式. 此文为原创,转摘请注明转摘自

java NIO socket 通信实例

java Nio 通信与Bio通信主要不同点: 1.Nio中的单个channel即可支持读操作也可以支持写操作,而bio中读操作要用inputstream,写操作要outputstream. 2.nio 采用byteBuffer 作为内存缓存区,向channel里写或者度操作,bio基本是用byte[] 3.nio采用 selector组件轮询读取就绪channel 服务端demo代码: package com.my.socket3; import java.io.ByteArrayOutput

java下socket传文件

package cn.stat.p4.ipdemo; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.ne