基于TCP/IP协议的Socket编程

如今的大多数网络通信都是选择使用基于TCP/IP的协议进行,其中封装的比较好的当属socket了,下面就socket的使用进行详细的描述:

一、Socket的工作模式

在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户/服务器(C/S)模式,即客户向服务器发出服务请求,服务器接收到请求后,提供相应的服务。主要工作模式可以描述如下:

服务器端:(首先服务器要先启动,服务器根据请求提供相应服务)

(1)打开一通信通道并告知本地主机,它愿意在某一公认地址上的某端口接收客户请求;

(2)等待客户请求到达该端口;

(3)接收到客户端的服务请求时,处理该请求并发送应答信号。当多任务的服务器接收到并发服务请求,会激活一新进程来处理这个客户请求。新进程处理此客户请求,并不需要对其它请求作出应答。服务完成后,关闭此新进程与客户的通信链路,并终止。

(4)返回第(2)步,等待另一客户请求。

(5)关闭服务器

客户端:

(1)打开一通信通道,并连接到服务器所在主机的特定端口;

(2)向服务器发服务请求报文,等待并接收应答;继续提出请求

(3)请求结束后关闭通信通道并终止。

二、工作原理


注:图片来源于网络百度百科。

(1)建立连接(三次握手)

客户端调用connect时,触发了连接请求,向服务器发送数据包,然后connect进入阻塞状态;服务器监听到连接请求调用accept函数接收请求向客户端发送确认数据包,然后accept进入阻塞状态;客户端收到服务器的确认数据包之后connect返回,并对数据包进行确认;服务器收到客户端的数据包时accept返回,通过三次握手建立连接。

(2)进行通信

服务器根据客户端的请求进行相应的应答。

(3)关闭连接(四次握手)

某个应用进程首先调用close主动关闭连接,这时TCP发送一个结束信号;服务器接收信号之后,执行被动关闭,

对这个信号进行确认。服务器发送一个确认信号给客户端,接收到文件结束符的应用进程调用close关闭它的socket,

最后向服务器发送一个确认信号。

三、一个具体的实例实现服务器和客户端的通信

服务器:

package connection;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * User: dsy
 * Date: 17-3-28
 * Time: 上午9:44
 * To change this template use File | Settings | File Templates.
 */
public class Server {

    public static void main(String args[]) throws IOException {
        int port = 5678;
        //定义一个ServerSocket监听在端口5678上
        ServerSocket server = new ServerSocket(port);
        while (true) {
            //server尝试接收其他Socket的连接请求(阻塞式的)
            Socket socket = server.accept();
            //接收到一个Socket就建立一个新线程来处理
            new Thread(new Task(socket)).start();
        }
    }

    /**
     * 用来处理Socket请求的
     */
    static class Task implements Runnable {

        private Socket socket;

        public Task(Socket socket) {
            this.socket = socket;
        }

        public void run() {
            try {
                handleSocket();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 跟客户端Socket进行通信
         */
        private void handleSocket() throws Exception {
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String temp;
            int index;
            while ((temp=br.readLine()) != null) {
                if ((index = temp.indexOf("end")) != -1) {//遇到end时就结束接收
                    sb.append(temp.substring(0, index));
                    break;
                }
                sb.append(temp);
            }
            System.out.println("receive from client: " + sb);
            //输入发送信息
            System.out.println(" send info:");
            Writer writer = new OutputStreamWriter(socket.getOutputStream());
            Scanner in = new Scanner(System.in);
            String s = in.nextLine();
            writer.write(s);
            writer.write("end\n");
            writer.flush();
            writer.close();
            br.close();
            socket.close();
        }
    }
}
客户端:

package connection;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * User: dsy
 * Date: 17-3-28
 * Time: 上午9:52
 * To change this template use File | Settings | File Templates.
 */
public class Client {

    public static void main(String args[]) throws Exception {
        String host = "localhost";  //要连接的服务器IP地址
        int port = 5678;   //要连接的服务器端口号
        //与服务器建立连接
        Socket client = new Socket(host, port);
        //往服务端写数据
        System.out.println("Send info:");
        Writer writer = new OutputStreamWriter(client.getOutputStream());
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        writer.write(s);
        writer.write("end\n");
        writer.flush();
        //从服务器接受数据
        BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String temp;
        int index;
        while ((temp=br.readLine()) != null) {
            if ((index = temp.indexOf("end")) != -1) {
                sb.append(temp.substring(0, index));
                break;
            }
            sb.append(temp);
        }
        System.out.println("receive from server: " + sb);
        writer.close();
        br.close();
        client.close();
    }
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值