socket通信

   Socket是网络上运行的两个程序间双向通信的一端,它既可以接受请求,也可以发送请求。


利用它可以较为方便的实现网络上数据的传递。在JAVA中,有专门的socket类来处理用户的请求和相应。


   Socket有两种主要的操作方式:面向连接的和无连接的。


   面向连接的socket操作就像是一部电话,他们必须建立一个连接和呼叫。它使用的TCP协议


在这个模式下建立的socket连接必须在发送数据之前与目的地的socket取得一个连接。一旦连接建立,


socket就可以使用一个流:打开->读->写->关闭。所有发送的信息都会在另一端以同样的顺序被接收。


面向连接的操作比无连接的操作效率更低,但是数据的安全性更高。


   无连接的socket操作就像是一个邮件投递,没有什么保证,多个邮件可能到达的时间顺序和出发顺序不同。


它使用的是数据报(UDP)协议。这个模式下的socket不需要连接一个目的地的socket,它只是简单的透出数据报。


无连接的操作是快速和高效的,但是数据安全性不佳。


   两种传输协议的比较:

       UDP:1,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。


                  2,UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。

 
                  3,UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方


       TCP:1,面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中需要连接


                     时间。


                  2,TCP传输数据大小限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大的  


                      数据。


                  3,TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。

  Socket通讯的过程


    Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息

一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。


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


  (1) 创建Socket;


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


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


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

  简单socket实例:

   服务端:

package com.htxx.action.JAVA;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
        ServerSocket serverSocket=null;
        //用于向客户端打印输出
        PrintWriter writer=null;
        try {
        	//实例化一个服务器端的socket连接
			serverSocket=new ServerSocket(9999);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("could not listen on port:9999");
			System.exit(1);
		}
        Socket clientSocket=null;
        try {
        	//accept方法用来监听客户端连接
        	//accept方法用于接收客户端的socket请求
			clientSocket=serverSocket.accept();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("accpet failed");
			System.exit(1);
		}
    	//通过客户端的socket对象去实例化printwriter对象,
    	//此时writer就具备了向客户端打印信息的能力
		writer=new PrintWriter(clientSocket.getOutputStream(), true);
        //打印信息至客户端
        writer.println("hello world");
        clientSocket.close();
        serverSocket.close();
        //writer.close();
        
        
	}

}
客户端:

package com.htxx.action.JAVA;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketClient {
   public static void main(String[] args) throws IOException {
	    Socket socketClient=null;
	    //用于读取服务器端发送过来的数据
	    BufferedReader reader=null;
	    //输入输出流与socket关联
	    try {
			socketClient=new Socket("localhost", 9999);
		    reader=new BufferedReader(
		    		new InputStreamReader(socketClient.getInputStream()));
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			System.out.println("unkown host");
			System.exit(1);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("i/o exception");
			System.exit(1);
		}
	    System.out.println(reader.readLine());
	    reader.close();
	    socketClient.close();

}
}
服务端启动后,等待客户端连接,客户端连接服务端,服务端发送消息给客户端。


可对话的Socket:

  服务端:

package com.htxx.action.JAVA;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class EchoServer {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        ServerSocket serverSocket=null;
        PrintWriter out=null;
        BufferedReader in=null;
        try {
			serverSocket=new ServerSocket(9999);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("could not listen on port:9999");
			System.exit(1);
		}
        Socket incoming=null;
        while(true){
        	try {
        		//使用accept()z阻塞等待客户请求,有客户请求到来
        		//则产生一个socket对象,并继续执行
				incoming=serverSocket.accept();
				//
				out=new PrintWriter(incoming.getOutputStream(), true);
				//将字节流放入字符缓冲流当中
				in=new BufferedReader(
						new InputStreamReader(incoming.getInputStream()));
				//提示信息
				//out.println("hello~~");
				out.println("这里是服务端~~");
				//out.flush();
				//在没有异常的情况下不断循环
				while(true){
					//只有当用户输入数据的时候才返回数据内容
					String str=in.readLine();
					//当用户断开连接时会返回空null
					if(str==null){
						//退出循环
						break;
					}else{
						//退出命令
						if(str.trim().equalsIgnoreCase("BYE")){
							break;
						}
						//控制台输入响应内容
						System.out.println("客户端:"+str);
						Scanner scanner=new Scanner(System.in);
						String reponse=scanner.nextLine();
						//向客户端输出内容
						out.println(reponse);
						//刷新输出流,使client马上收到该字符串
						out.flush();
						System.out.println("我:"+reponse);
					}
				}
				
				out.close();
				in.close();
				incoming.close();
				serverSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        	
        }
        
	}

}
 客户 端:

package com.htxx.action.JAVA;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import com.microsoft.schemas.vml.STTrueFalse;

public class EchoClient {
    public static void main(String[] args) throws IOException {
	    Socket socketClient=null;
	    //用于读取服务器端发送过来的数据
	    BufferedReader in=null;
	    //发送消息到服务端
	    PrintWriter out=null;
	    //输入输出流与socket关联
	    try {
	    	//向本机的9999端口发出客户请求
			socketClient=new Socket("localhost", 9999);
		    in=new BufferedReader(
		    		new InputStreamReader(socketClient.getInputStream()));
		    out=new PrintWriter(socketClient.getOutputStream(),true);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			System.out.println("unkown host");
			System.exit(1);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("i/o exception");
			System.exit(1);
		}
	    //从控制台输入内容
	    while(true){
	    	String str=in.readLine();
	    	if(str==null){
	    		break;
	    	}else{
		    	if(str.equalsIgnoreCase("BYE")){
		    		break;
		    	}else{
		    		System.out.println("服务端:"+str);
					Scanner scanner=new Scanner(System.in);
					String reponse=scanner.nextLine();
					out.println(reponse);
					System.out.println("我:"+reponse);
		    	}
	    	}
	    }
	    in.close();
	    out.close();
	    socketClient.close();
	}
}
测试:

  先启动服务端,再启动客户端:

客户端发送消息给服务端:


查看服务端:

服务端向客户端发消息:

查看客户端:



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值