欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java通过 Socket 实现 TCP服务端

程序员文章站 2024-02-23 08:22:22
1 java socket简介   所谓socket 通常也称作”套接字“,用于描述ip地址和端口,是一个通信链的句柄。应用程序通常通过”套接字”向网络发出请求或者应答网...

1 java socket简介

  所谓socket 通常也称作”套接字“,用于描述ip地址和端口,是一个通信链的句柄。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。socket和serversocket类库位于java.net包中。serversocket用于服务器端,socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。

2 tcpserver代码实例

import java.io.ioexception;
import java.io.inputstream;
import java.io.outputstream;
import java.net.serversocket;
import java.net.socket;
import java.util.date;
import java.util.hashmap;
import java.util.map;

import org.slf4j.logger;
import org.slf4j.loggerfactory;

/**
 * tcp服务器端,单例模式
 * @author xiang
 *
 */
public class tcpserver implements runnable {
  private static final logger logger = loggerfactory.getlogger(tcpserver.class);
  //成员变量/
  private static tcpserver serverinstance;      
  private static map<string, socketthread> socketmaps = new hashmap<string,socketthread>();        //每个客户端连接时都会新建一个socketthread与之对应  private static serversocket serversocket;          //服务器套接字
  private static int serport = 9999;              //服务器端口号
  private static boolean flag;                //服务器状态标志
  private static final int buffer_size = 512;          //数据接收字符数组大小
  
  //构造函数/
  private tcpserver() {
    
  }
  
  /**
   * 获取实例
   * @return tcpserver实例serverinstance
   */
  public static tcpserver getserverinstance(){
    if(serverinstance==null)
      serverinstance = new tcpserver();
    return serverinstance;
  }
  
  /**
   * 开启服务器
   * @throws ioexception
   */
  public void opentcpserver() throws ioexception{    if(serversocket==null || serversocket.isclosed()){
      serversocket = new serversocket(serport);
      flag = true;
    }
  }
  
  /**
   * 关闭服务器
   * @throws ioexception 
   */
  public void closetcpserver() throws ioexception{
    flag = false;   if(serversocket!=null)
      serversocket.close();
    /*for (map.entry<string, socketthread> entry : socketmaps.entryset()) { 
       system.out.println("key = " + entry.getkey() + ", value = " + entry.getvalue());     
    } */ 
    for (socketthread value : socketmaps.values()) 
      value.closeconnect();
    socketmaps.clear();    
  }
  
  /**
   * 服务器向客户端发送数据
   * @param bytes[]:待发送的字符数组
   * @param key 客户端的key,为空或""时表示数据群发
   * @throws ioexception 
   */
  public void sendmessage(string key,byte[] msgbytes){
    if(key==null||key.equals("")){
      for (socketthread value : socketmaps.values()) 
        value.sendmassage(msgbytes);
    }else{
      socketthread thread = socketmaps.get(key);
      if(thread!=null)
        thread.sendmassage(msgbytes);
    }
  }
  
  /**
   * 服务器向客户端发送数据
   * @param key 客户端的key,为空或""时表示数据群发
   * @param msgstr:待发送的字符串
   * @throws ioexception 
   */
  public void sendmessage(string key,string msgstr){   byte[] sendbyte = msgstr.getbytes();
    if(key==null||key.equals("")){
      for (socketthread value : socketmaps.values()) 
        value.sendmassage(sendbyte);
    }else{
      socketthread thread = socketmaps.get(key);
      if(thread!=null)
        thread.sendmassage(sendbyte);
    }
  }
  
  @override
  public void run() {
    logger.info("服务器线程已经启动");   while(true){
      try {
        while(flag){
          logger.info("服务器线程在监听状态中");
          socket socket = serversocket.accept();
          string key = socket.getremotesocketaddress().tostring();
          socketthread thread = new socketthread(socket,key);
          thread.start();
          socketmaps.put(key, thread);          
          logger.info("有客户端连接:"+key);
        }        
      } catch (exception e) {
        e.printstacktrace();        
      } 
    }
  }     
  
  /**
   * 处理连接后的数据接收请求内部类
   * @author xiang
   *
   */
  private class socketthread extends thread{
    private socket socket;
    private string key;
    private outputstream out;
    private inputstream in;
    
    //构造函数
    public socketthread(socket socket,string key) {
      this.socket = socket;
      this.key = key;
    }
    
    /**
     * 发送数据
     * @param bytes
     * @throws ioexception 
     */
    public void sendmassage(byte[] bytes){
      try {
        if(out==null)
          out = socket.getoutputstream();
        out.write(bytes);
      } catch (exception e) {
        e.printstacktrace();
        try {
          closeconnect();
        } catch (ioexception e1) {
          e1.printstacktrace();
        }
        socketmaps.remove(key);        
      } 
    }

    /**
     * 关闭连接,释放资源
     * @throws ioexception 
     */
    public void closeconnect() throws ioexception{
      if(out!=null)  out.close();
      if(in!=null)  in.close();
      if(socket!=null && socket.isconnected())  socket.close();
    }
    
    @override
    public void run() {
      byte[] receivbuf = new byte[buffer_size];
      int recvmsgsize;
      try {
        in = socket.getinputstream();
        out = socket.getoutputstream();
        while ((recvmsgsize = in.read(receivbuf)) != -1) {
          string receiveddata = new string(receivbuf, 0, recvmsgsize);
          system.out.println("reverve form[port" + socket.getport() + "]:" + receiveddata);
          system.out.println("now the size of socketmaps is" + socketmaps.size());
          /**************************************************************
           * 
           * 接收数据后的处理过程
           * 
           **************************************************************/
        }
        // response to client
        byte[] sendbyte = "the server has received".getbytes();
        // out.write(sendbyte, 0, sendbyte.length);
        out.write(sendbyte);
        system.out.println("to cliect[port:" + socket.getport() + "] 回复客户端的消息发送成功");
        closeconnect();
        socketmaps.remove(key);        
      } catch (exception e) {
        e.printstacktrace();
        try {
          closeconnect();
        } catch (ioexception e1) {
          e1.printstacktrace();
        }
      }
    }
    
    //////////////
    public int getport(){
      return socket.getport();
    }
  }
  //. end socketthread  
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!