Socket编程浅说

关于Socket,本篇博客只为方便自己记忆,具体细节请查看下方地址:
http://www.cnblogs.com/linzheng/archive/2011/01/23/1942328.html

http://acm.tzc.edu.cn/acmhome/projectList.do?method=projectNewsDetail&nid=2

注意:本篇博客纯粹是为了方便自己记忆查阅用的,如果查看Socket资料的同行看到了,烦请查看上面两个地址,我这块跳过即可。

一、Socket的定义:
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。

但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。

二、Socket通讯的过程
Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。

对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:

  (1) 创建Socket;

  (2) 打开连接到Socket的输入/出流;

  (3) 按照一定的协议对Socket进行读/写操作;

  (4) 关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)

三、TCP协议下使用Socket编程的三种情况
1.客户端给服务端发送数据,服务端接收数据
2.客户端发送内容给服务端,服务端给予反馈
3.从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接

首先,我们来看一下第一种情况下的简单代码:

public class TCPTest1 {

//注意:
// 异常需要使用try-catch-finally处理,保证流和Socket都可以被关闭
// 需要先开启服务端,再开启客户端

// 客户端
@Test
public void client(){
    //2.创建一个Socket,用于数据的发送和接收,//形参指明对方的(服务端)的ip地址和端口号
    Socket ss = null;
    //3.通过socket获取一个输出流
    OutputStream os = null;
    try {
        //1.创建一个InetAddress类的对象
        InetAddress inet = InetAddress.getByName("192.168.56.1");
        ss = new Socket(inet, 8989);
        os = ss.getOutputStream();
        //4.输出流输出数据
        os.write("I Love You".getBytes());
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
        //5.关闭相应的流和socket
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (ss != null) {
            try {
                ss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

//服务端
@Test
public void server(){
    //1.创建一个ServerSocket的对象]
    ServerSocket ss = null;
    //2.调用accept(),返回Socket的对象
    Socket s = null;
    //3.通过Socket获取一个输入流
    InputStream is = null;
    try {
        ss = new ServerSocket(8989);

        s = ss.accept();

        is = s.getInputStream();

        //4.通过输入流,读取数据
        byte[] b = new byte[20];
        int len;
        while ((len = is.read(b))!= -1) {
            String str = new String(b, 0, len);
            System.out.println(str);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        if (s != null) {
            try {
                s.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (ss != null) {
            try {
                ss.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }


}
}

第二种情况下的简单代码:

public class TCPTest2 {

//正常都应该使用try-catch-finally处理异常

    //客户端
    @Test
    public void client() throws Exception{
        //1.
        Socket socket = new Socket(InetAddress.getByName("192.168.56.1"), 9898);
        //2.
        OutputStream os = socket.getOutputStream();
        //3.
        os.write("客户端请求一个静美的女子做妻子".getBytes());
        //关闭输出
        socket.shutdownOutput();
        //4.
        InputStream is = socket.getInputStream();
        //5.
        byte[] b = new byte[200];
        int len;
        while((len = is.read(b)) != -1){
            String str = new String(b,0,len);
            System.out.println(str);
        }

        //6.
        is.close();
        os.close();
        socket.close();
        }

    //服务端
    @Test
    public void server() throws Exception{
        //1.
        ServerSocket ss = new ServerSocket(9898);
        //2.
        Socket s = ss.accept();
        //3.
        InputStream is = s.getInputStream();
        //4.
        byte[] b = new byte[200];
        int len;
        while((len = is.read(b)) != -1){
            String str = new String(b,0,len);
            System.out.println(str);
        }
        System.out.println(s.getInetAddress().getHostAddress());

        //5.
        OutputStream os = s.getOutputStream();
        os.write("服务端准了".getBytes());
        s.shutdownOutput();
        //6.
        os.close();
        is.close();
        s.close();
        ss.close();

    }
    }

第三种情况下的简单代码:

public class TCPTest3 {

//客户端
    @Test
    public void client() throws Exception{
        //1.创建一个Socket,用于数据的发送和接收,//形参指明对方的(服务端)的ip地址和端口号
        Socket socket = new Socket(InetAddress.getByName("192.168.56.1"), 8888);

        //2.用于给客户端发送数据流
        OutputStream os = socket.getOutputStream();
        //3.用于从本地读取图片
        FileInputStream fis = new FileInputStream(new File("zjr1.jpg"));
        //4.将图片转化成流的形式,并以流的形式输出
        byte[] b = new byte[30];
        int len;
        while((len = fis.read(b)) != -1){
            os.write(b, 0, len);
        }
        //5.关闭socket
        socket.shutdownOutput();

        //6.接收从服务端发来的“发送成功”字节流
        InputStream is = socket.getInputStream();
        byte[] buffer = new byte[20];
        int length;

        while((length = is.read(buffer)) != -1){
            String str = new String(buffer,0,length);
            System.out.print(str);
        }
        //7.由内而外的关闭
        is.close();
        os.close();
        fis.close();
        socket.close();

    }

    //服务端
    @Test
    public void server() throws Exception{
        //1.创建服务端的ServerSocket
        ServerSocket ss = new ServerSocket(8888);
        //2.调用accept(),返回Socket的对象
        Socket s = ss.accept();
        //3.创建输入流的对象
        InputStream is = s.getInputStream();
        //4.将接收到的图片输出保存到本地
        FileOutputStream fos = new FileOutputStream(new File("zjr2.jpg"));
        //5.以字节的方式输出到本地
        byte[] b = new byte[30];
        int len;
        while((len = is.read(b)) != -1){
            fos.write(b, 0, len);
        }

        //6.输出发送成功
        OutputStream os = s.getOutputStream();
        os.write("发送成功".getBytes());
        //7.关闭
        os.close();
        fos.close();
        is.close();
        s.close();
        ss.close();
    }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值