socket示例

先贴代码:

一、服务器端线程
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

/**
 * PolyLink 服务器端线程
 * @author Administrator
 * 
 */
public class PolyLinkServerThread implements Runnable {
 Socket client;
 DataInputStream input;
 DataOutputStream output;
 public PolyLinkServerThread(Socket client) throws IOException {
  this.client = client;
  input = new DataInputStream(client.getInputStream());
  output = new DataOutputStream(client.getOutputStream());
  output.flush();
  client.setSoTimeout(3000);
 }
 public void run() {
  try {
   //开始接收
   List<Integer> list = new ArrayList<Integer>();
   while(true){
    int num = 0;
    try{
     num = input.readInt();
    }catch(SocketException e){
     break;
    }catch(EOFException e){//如果读到文件末尾会发生这个异常,看JAVA的API
     break;
    }catch(Exception e){
     break;
    }
    list.add(num);
   }
   int []intArr = new int[list.size()];
   for(int i=0;i<list.size();i++){
    intArr[i] = list.get(i);
   }
   String recieveMessage =StringUtil.asciiToString(intArr);
   //开始发送回执信息
   String returnMessage = validateMessage(recieveMessage);
   int[]ascii = StringUtil.stringToAscii(returnMessage);
   for(int i:ascii){
    output.writeInt(i);
   }
   input.close();
   output.close();
   client.close();
  }catch (Exception e) {
   e.printStackTrace();
  } 
 }
 /**
  * 根据接受的消息返回一个需要返回消息的字符串
  * @return
  */
 public String validateMessage(String recieveMessage){
  System.out.println("服务器端接收到的消息为:"+recieveMessage);
  return "根据接收信息格式不同生成不同的回执信息";
 }
}

二、服务端

import java.net.ServerSocket;
import java.net.Socket;

/**
 * PolyLink服务器
 * @author Administrator
 *
 */
public class PloyLinkServer {

 public   final   static   int   PORT   =   8989;   
    /**
     * 启动PloyLinkServer服务
     * @param args
     */
    public static void startPloyLinkServer()   {   
        ServerSocket   serverSocket   =   null;   
        Socket socket = null;
        try {   
            serverSocket = new ServerSocket(PORT);   
            while (true)   {   
             socket = serverSocket.accept();
             PolyLinkServerThread lpst = new PolyLinkServerThread(socket);  
                ThreadPool.setProducerPool(lpst);
            }   
        }catch   (Exception   ex)   {   
            ex.printStackTrace();   
        }   
    }   
    public static void main(String []args) throws InterruptedException{
     startPloyLinkServer();
    }
}
三、客户端

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * PolyLink客户端
 * @author Administrator
 *
 */
public class PolyLinkClient{
 public Socket socket = null;
 OutputStream netOut = null;
 DataOutputStream out = null;
 DataInputStream in = null;
 
 public PolyLinkClient() throws UnknownHostException, IOException{
  socket = new Socket("192.163.35.114", 8989);
  socket.setSoTimeout(10000);
  netOut = socket.getOutputStream();
  out = new DataOutputStream(netOut);
  in = new DataInputStream(socket.getInputStream());
 }
 /**
  * 给服务器发报文,并返回接收报文
  */
 public String sendMessageByASCII(String message){
  String recieveMessage = "";
  try {
   //开始发送
   int[]ascii = StringUtil.stringToAscii(message);
   out.flush();
   for(int i:ascii){
    out.writeInt(i);
   }
   //开始接收
   List<Integer> list = new ArrayList<Integer>();
   while(true){
    int num = 0;
    try{
     num =  in.readInt();
    }catch(EOFException e){
     break;
    }catch(Exception e){
     break;
    }
    list.add(num);
   }
   int []intArr = new int[list.size()];
   for(int i=0;i<list.size();i++){
    intArr[i] = list.get(i);
   }
   recieveMessage =StringUtil.asciiToString(intArr);
   in.close();
   out.close();
   socket.close();
  }catch (UnknownHostException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  return recieveMessage;
 }

 public static void main(String []args) throws InterruptedException, UnknownHostException, IOException{
     PolyLinkClient p = new PolyLinkClient();
     String sendMssage = "8d431f27280a4a7b8c1a0d2f29bdb9a4TART:START:66667890"+"TART:START:66667890\r\nRECV-IP:192.168.17.33\r\nRECV-PORT:1234\r\nPAYLOAD-TYPE:TS\r\n\r\n";
     String recieveMessage = p.sendMessageByASCII(sendMssage);
     System.out.println("客户端接受的消息为:"+recieveMessage);
 }
}
四、线程池

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池
 * @author Administrator
 *
 */
public class ThreadPool {
    /**
  * 构造一个线程池.核心线程一个,最大线程数100.线程队列容纳10个。超出最大线程数的处理策略为重蹈覆添加该线程,知道添加成功为止
  */
    private static ThreadPoolExecutor producerPool = new ThreadPoolExecutor(1, 100, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10), new ThreadPoolExecutor.CallerRunsPolicy());
 /**
  * 把PolyLinkServerThread线程放到了线程池中,具体的线程执行由线程池操作
  * @param thread
  */
 public static void setProducerPool(PolyLinkServerThread lpst) {
  producerPool.execute(lpst);
    }
}        
五。ascii转换函数

 /**
  * 字符串转ascii码,包含中文
  * @param str
  * @return
  */
 public static int[] stringToAscii(String str) {
  char[] chars = str.toCharArray();
  int intArr[]= new int[chars.length];
  for (int i=0;i<chars.length;i++) {// 输出结果
   intArr[i] = (int)chars[i];
  }
  return intArr;
 }

代码编写过程中遇到错误多多,以前都是做个示例,没这么多错误哇。。。

错误一、

java.net.SocketException:   Connection   reset

这个是由于client端发数据的时候发完没有关闭in,out,server造成的。还有服务器端的读取in.readInt()函数也造成这个错误。另外,服务器端读取的时候,in.available()这个函数是非常非常不靠谱的。因为socket发送时候网络上的岩石,available()这个函数不能正确的反映出可读的字节数量、正确的做法是用eofException这个异常来判断读取结束。

错误二、

Exception。。。closed by peer

当服务端接受了客户端的数据以后,会向客户端发送数据,但是这个时候客户端已经关闭了!⊙﹏⊙b汗!。此时就要这样

output.flush();
client.setSoTimeout(3000);

用一下out,然后客户端等待一会儿。不知道为什吗,output.flush();这个必须要。+_+

问题三、就是要深入的研究一下这个线程池
ThreadPool。。啦啦啦这个以后再弄了
 

猜你喜欢

转载自lvwenwen.iteye.com/blog/1545330