zoukankan      html  css  js  c++  java
  • Socket网络编程

    最近写Socket网络编程,服务器端接收数据老是不全。困扰了一个多星期,还以为是TCP的问题,后来找老大给我修改了一下程序。原因实际上还是我对TCP协议的运转机制不够熟悉,程序不够严谨。先把写好的程序贴在下面,以后有了感悟再在这个基础上修改,有问题大家也可以在下面留言给我。

    客户端代码如下:
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;

    public class TCPClient{
        public static void main(String[] args){
            
            try {
                Socket socket = new Socket("192.168.1.41",5500);
                OutputStream outputStream = socket.getOutputStream();
                byte[] b_data = new byte[75];
                b_data[0]=0x01;  //设备号
                b_data[1]=0x00;
                b_data[2]=0x00;
                b_data[3]=0x00;
                
                b_data[4]=0x01;  //发送者标志
                b_data[5]=0x02;   //接受者标志
                b_data[6]=0x02;    //消息标志
                b_data[7]=0x43;   //消息长度
                
                
        
                b_data[8]=0x01;    //用户信息序号   
                b_data[9]=0x00;
                b_data[10]=0x00;        
                b_data[11]=0x00;
                
                b_data[12]=0x10;   //消息类型
                b_data[13]=0x3d;    //参数长度
              
                //参数
                b_data[14]=0x33;
                b_data[15]=0x0c;
                
                b_data[16]=0x34;   //IMSI
                b_data[17]=0x36;
                b_data[18]=0x30;
                b_data[19]=0x30;
                b_data[20]=0x30;
                b_data[21]=0x31;
                b_data[22]=0x32;
                b_data[23]=0x33;
                b_data[24]=0x34;
                b_data[25]=0x35;
                b_data[26]=0x36;
                b_data[27]=0x37;
                b_data[28]=0x38;
                b_data[29]=0x39;
                b_data[30]=0x30;
                b_data[31]=0x00;
                
                b_data[32]=0x31;  //IMEI
                b_data[33]=0x32;
                b_data[34]=0x33;
                b_data[35]=0x34;
                b_data[36]=0x35;
                b_data[37]=0x36;
                b_data[38]=0x31;
                b_data[39]=0x32;
                b_data[40]=0x31;
                b_data[41]=0x32;
                b_data[42]=0x33;
                b_data[43]=0x34;
                b_data[44]=0x35;
                b_data[45]=0x36;
                b_data[46]=0x31;
                b_data[47]=0x00;
                
                b_data[48]=0x38;  //信号强度
                b_data[49]=0x00;
                
                b_data[50]=0x00;  //用户状态
                
                /*ba_data[51]=0x00;  //时间
                ba_data[52]=0x00;
                ba_data[53]=0x00;
                ba_data[54]=0x00;
                ba_data[55]=0x00;
                ba_data[56]=0x01;
                ba_data[57]=0x00;
                
                ba_data[58]=0x03;  //日期
                ba_data[59]=0x00;
                ba_data[60]=0x05;
                ba_data[61]=0x00;
                ba_data[62]=0x00;
                ba_data[63]=0x07;
                ba_data[64]=0x00;*/
                
                
                b_data[51]=0x00;  //纬度
                b_data[52]=0x33;
                b_data[53]=0x33;
                b_data[54]=0x33;
                b_data[55]=0x33;
                b_data[56]=0x33;
                b_data[57]=0x33;
                b_data[58]=0x2e;
                b_data[59]=0x33;
                b_data[60]=0x33;
                b_data[61]=0x33;
                b_data[62]=0x00;
                        
                b_data[63]=0x00;  //经度
                b_data[64]=0x33;
                b_data[65]=0x33;
                b_data[66]=0x33;
                b_data[67]=0x33;
                b_data[68]=0x33;
                b_data[69]=0x33;
                b_data[70]=0x2e;
                b_data[71]=0x33;
                b_data[72]=0x33;
                b_data[73]=0x33;
                b_data[74]=0x00;
                byte[] temp = new byte[b_data.length + 4];
                temp[0] = (byte) 0x60;
                temp[1] = (byte) 0x70;
                temp[2] = (byte) 0x80;
                temp[3] = (byte) 0x90;
                System.arraycopy(b_data, 0, temp, 4, b_data.length);
                int count = 0;
                
            for(int i=0;i<100000;i++){
            count++;
                byte[] b = new byte[4];
                for (int j = 0; j < 4; j++) {
                    b[j] = (byte) ((count >> 8 * j) & 0xFF);
                    temp[12+j]=b[j];  
                }
                outputStream.write(temp);
                outputStream.flush();//刷新输出流      
            }
            socket.close();
            }catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
    服务器端代码如下:

    package mars.socket;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;

    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;

    public class SocketActivity extends Activity {
        /** Called when the activity is first created. */
        private Button startButton;
        private InputStream inputStream=null;
        private ServerSocket serverSocket=null;
        private Socket socket=null;
        private Queue<TempValue> buffer_queue = new LinkedList<TempValue>();;
        private ReadWriteLock myLock = new ReentrantReadWriteLock() ;


        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            startButton = (Button)findViewById(R.id.startListener);
            startButton.setOnClickListener(new StartSocketListener());
        }
        
        class StartSocketListener implements OnClickListener{

            @Override
            public  void onClick(View v) {
                buffer_queue.clear();
                ServerThread  main=new ServerThread();
                main.start();
                ManageTcpInfoThread manageThread = new ManageTcpInfoThread();
                Thread m = new Thread(manageThread);
                m.start();
                
            }
        }
        
        class ServerThread extends Thread{
            public void run(){
                
                while(true){
                            try {
                                serverSocket = new ServerSocket(5500);
                                socket = serverSocket.accept();
                                System.out.println("recieve connect socket:"+socket);
                                ReadTcpInfoThread t=new ReadTcpInfoThread(socket);
                                Thread r = new Thread(t);
                                //r.setPriority(MAX_PRIORITY);
                                r.start();
                            } catch (IOException e) {
                                 //TODO Auto-generated catch block
                                e.printStackTrace();
                                break;
                            }
                                try {
                                    serverSocket.close();
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                }
            }
      }
        public class ReadTcpInfoThread implements Runnable{
            private Socket socket;
            private int len;
            byte[] buffer = new byte[268];
            
            private int count=0;

            public ReadTcpInfoThread(Socket s){
                this.socket=s;
            }
            
    /*        public void finalize()
            {
                try {
                    System.out.println("socket close"+socket);
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }*/
            
            public void run(){
                    try {
                        inputStream = socket.getInputStream();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    int packetnum=0;
                    try {
                    while(true){
                        int i=inputStream.read(buffer,count,1);    //之前采用的方法是一次读12个字节,因为觉得一次读一个字节太慢了,老大说计算机运行的速度每秒十几亿次

                                                                                   //这样每次读一个字节比较保险,并且读不到数据(即i=-1的时候)要跳出来关闭socket。
                        if(i==-1)
                        {
                            System.out.println("socket disconnect"+socket);
                            socket.close();
                            break;
                        }
                        if(count==0){
                                if(buffer[count]!=(byte)0x60){
                                    break;
                                }
                            }
                        if(count==1){
                            if(buffer[count]!=(byte)0x70){
                                count=0;
                                break;
                            }
                        }
                        if(count==2){
                            if(buffer[count]!=(byte)0x80){
                                count=0;
                                break;
                            }
                        }
                        if(count==3){
                            if(buffer[count]!=(byte)0x90){
                                count=0;
                                break;
                            }
                        }
                        if(count==11){
                            len=buffer[count]&0xff;
                        }
                        if(count==len+11){
                            byte[] pack = new byte[8+len];
                            System.arraycopy(buffer, 4, pack, 0,len+12-4);
                            TempValue o = new TempValue(pack,len+12-4);
                            packetnum++;
                            System.out.println("read a packet packetnum="+packetnum);
                            myLock.writeLock().lock();
                            buffer_queue.offer(o);
                            myLock.writeLock().unlock();
                            count=0;
                            continue;
                        }

                       count++;
     
                    
                        }
                    }catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
        }
       public class ManageTcpInfoThread implements Runnable{
           byte[] recv_buff;
           TempValue p;
           int pollnum;
           int sleepnum;
           int handledpacketnum;
           public void run()
           {
               pollnum=0;
               sleepnum=0;
               handledpacketnum=0;
               while(true){
                   pollnum++;
                   
               myLock.writeLock().lock();
               p=buffer_queue.poll();
               myLock.writeLock().unlock();
               if(p==null||p.rec_len!=p.buf[7]+8)
               {
                   sleepnum++;
               try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                     //TODO Auto-generated catch block
                    e.printStackTrace();
                }
                    continue;
               }
               else
               {
                   handledpacketnum++;
                   System.out.println("handledpacketnum="+handledpacketnum+"pollnum=" + pollnum+"sleepnum="+sleepnum);
                   System.out.println(SocketActivity.bytesToHexString(p.buf));
                    
               }
               }
               
           }

       }
       public static String bytesToHexString(byte[] src){  
            StringBuilder stringBuilder = new StringBuilder("");  
            if (src == null || src.length <= 0) {  
                return null;  
            }  
            for (int i = 0; i <  src.length ; i++) {  
                int v = src[i] & 0xFF;  
                String hv = Integer.toHexString(v);  
                if (hv.length() < 2) {  
                    stringBuilder.append(0);  
                }  
                stringBuilder.append(hv);  
            }  
            return stringBuilder.toString();  
        }  
       
       public class TempValue{
           private byte[] buf=new byte[75];
           private int rec_len;
           public TempValue(byte[] buf,int rec_len){
               this.buf=buf;
               this.rec_len=rec_len;
           }
       }
        
    用这个程序发送了十万个包,一个都没有丢。现在正在上班,有时间再补充,大家互相学习一下吧。

  • 相关阅读:
    包含了访问命名服务的类和接口
    JNDI架构提供了一组标准的独立于命名系统的API
    利用JNDI的命名与服务功能来满足企业级API对命名与服务的访问
    JNDI(Java Naming and Directory Interface,Java命名和目录接口)
    Servlet 国际化
    重要的调试技巧
    使用 JDB 调试器
    Servlet 调试
    Servlet 打包部署
    编译包中的 Servlet
  • 原文地址:https://www.cnblogs.com/leihupqrst/p/3110105.html
Copyright © 2011-2022 走看看