实现Socket通信

了几天TCP/IP协议和HTTP协议后,自己写了一个Demo用socket实现了一下(PC做服务器,Android做客户端),果然不动手不知道有些细节得注意。遇到最大的问题就是遇到这个异常java.net.SocketException: socket is closed 

单向传输数据的时候server与client是没有问题的,但是两个都有输入输出操作的时候就出现了上面这个问题。一般来说,流 得在finally中关闭,像out.close();bufferedReader.close();如果这样做就会出现上面的异常。

异常主要出现在socket.getOutputStream()或socket.getInputStream(),按照我的理解:bufferReader.close()与out.close()关闭会直接导致sockect。所以解决方法是:将out.close()与bufferReader.close()换成socket.shutdownOutput()与socket.shutdownInput(),就不会出现Socket直接被关闭的问题了。

shutdownInput()和close()的区别:shutdownInput和shutdownOutput没有关闭网络连接的功能,仅关闭输入流或仅关闭输出流。而close()方法还会将socket连接给关闭掉。

服务器端:

主要代码:

1.ServerSocket serverSocket = new ServerSocket(1989); //创建一个ServerSocket对象,并让这个Socket在1989端口监听

2.在While循环中,Socket socket=serverSocket.accept();//接受客户端所发送的请求。如果客户端没有发送数据,那么该线程就停滞不继续

3.在子线程中,socket.getOutputStream() ;或socket.getInputStream() ;//获取输入流来读取客户端内容和获取输出流来发送数据给客户端。如果用到缓冲,记得flush();

 

package pack;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketDemo {
      public static void main(String[] args) throws IOException{ 
            ServerSocket serverSocket = null;  
            // 创建一个ServerSocket对象,并让这个Socket在1989端口监听  
            serverSocket = new ServerSocket(1989);  
            // 调用ServerSocket的accept()方法,接受客户端所发送的请求,  
            // 如果客户端没有发送数据,那么该线程就停滞不继续  
            while (true) {  
                  //等待客户端连接  
                  Socket socket = serverSocket.accept();  
                  if(socket!=null)
                        new SocketThread(socket).start();  
                        new SocketThread2(socket).start();
              }              
      }
}

class  SocketThread extends Thread{
      Socket socket=null;
      public SocketThread(Socket socket){
            this.socket=socket;
      }
      public void run(){
            InputStream inputStream=null;
            try{
                  // 从Socket当中得到InputStream对象 ,读取客户端所发送的数据  
                  inputStream = socket.getInputStream();  
                  byte buffer[] = new byte[1024];  
                  int temp = 0;    
                  while ((temp = inputStream.read(buffer)) != -1) {  
                        System.out.println(new String(buffer, 0, temp));  
                  }  
                  
            } catch (IOException e) {  
                  e.printStackTrace();  
            } 
      }
}
class  SocketThread2 extends Thread{
      Socket socket=null;
      public SocketThread2(Socket socket){
            this.socket=socket;
      }
      public void run(){
            BufferedWriter writer=null;
            try{
                  // 从Socket当中得到OutputStream对象 ,发送数据给客户端 
                  writer =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                  writer.write("ServerSocket get!");
                  writer.flush();  //一定要的
                 
            } catch (IOException e) {  
                  e.printStackTrace();  
            }
      }           
 }


 

客户端:

主要代码:

1.在子线程中,Socket socket = new Socket("192.168.1.212", 1989);//创建一个Socket对象,传入服务器ip地址和端口号。

2.在子线程中socket.getOutputStream() ;或socket.getInputStream() ;//获取输入流来读取服务器内容和获取输出流来发送数据给服务器。如果用到缓冲,记得flush();

3.关流时:socket.shutdownOutput() ;或socket.shutdownInput();

一般输入和输出都单独开个子线程。

 

package com.liuzhcheng.socketdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class MainActivity extends Activity {
    Button send;
    EditText editText;
    TextView text;
    Handler handler;
    Socket socket;
    String str;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText=(EditText) findViewById(R.id.edit_data);
        text=(TextView) findViewById(R.id.server_text);
        handler=new Handler(){

            @Override
            public void handleMessage(Message msg) {
                if(msg.what==0x11){
                    text.setText((String)msg.obj);
                }
            }

        };

        send=(Button) findViewById(R.id.button_send);
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                str=editText.getText().toString();
                if(!TextUtils.isEmpty(str)) {
                    new Thread() {
                        public void run(){
                            try {
                                //连接服务器,ip地址和端口号
                              //  socket=new Socket();
                              //  socket.connect(new InetSocketAddress("192.168.1.212", 1989), 5000);
                                socket = new Socket("192.168.1.212", 1989);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (socket != null) {
                                new MyThread(str, socket).start();
                                new MyThread2(handler,socket).start();
                            }

                        }
                    }.start();

                }
            }
        });

    }

}


class MyThread extends Thread {
    String send_data;
    Socket socket=null;
    OutputStream out=null;
    public MyThread(String str,Socket socket) {
        send_data = str;
        this.socket=socket;
    }
    @Override
    public void run() {
        try {

            //获取输出流
            out= socket.getOutputStream();
            //向服务器发送信息
            out.write(send_data.getBytes("gbk"));
            out.flush();

            socket.shutdownOutput();//关流
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}


class MyThread2 extends Thread {
    Handler handler;
    Socket socket=null;
    InputStream in;
    public MyThread2(Handler handler,Socket socket) {
        this.handler=handler;
        this.socket=socket;
    }
    @Override
    public void run() {
        //定义消息
        Message msg = new Message();
        msg.what = 0x11;
        try {
            in=socket.getInputStream();
            int len;
            byte[] buf=new byte[1024];

            String str=null;
            while((len=in.read(buf))!=-1){
                str=new String(buf,0,len);
            }

            msg.obj=str;
            handler.sendMessage(msg);

            if(socket!=null){
                socket.shutdownInput();//关流
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值