欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

socket编程

程序员文章站 2022-04-08 21:38:58
...

Socket编程
ip和端口号:
IP和端口号组成网络地址
IP(Internet Protocol),网络之间互连的协议,IP地址是区分不同计算机的唯一标识
端口号是计算机逻辑通讯接口,不同的应用程序用不同的端口,网络应用程序的区分标识

        端口号一般使用2个字节(16bit)进行编号,最多可以有65536个端口,只有整数,范围是从0 到65535
        第一类:公认端口(Well Known Ports):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议,例如:80端口实际上总是HTTP通讯。
        第二类:注册端口(Registered Ports):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。
         第三类:动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口

TCP与UDP:
网络7层协议:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层
传输层的两个主要协议
TCP(Transmission Control Protocol)协议:传输控制协议,提供可靠无差错的数据传输,速度慢,占用系统资源高
UDP(User Datagram Protocol)协议:用户数据报协议,不可靠的数据传输,速度快,较安全。
Socket编程原理(基于TCP):
服务器端
(1) 创建ServerSocket对象,绑定监听端口;
(2) 通过accept()方法监听客户端请求;
(3) 连接建立后,通过输入流读取客户端发送的请求信息;
(4) 通过输出流向客户端发送相应信息;
(5) 关闭响应资源。
客户端
(1) 创建Socket对象,指明需要连接的服务器地址和端口;
(2) 连接建立后,通过输出流向服务器端发送请求信息;
(3) 通过输入流获取服务器端返回的响应信息;
(4) 关闭响应资源。
具体代码实现:
简单示例:
服务器:

 try {
			ServerSocket server = new ServerSocket(9000);
			System.out.println("服务器已经运行,等待客户端信息!");
			Socket socket = server.accept();
			BufferedReader  in = new BufferedReader(
				new InputStreamReader(socket.getInputStream()));
			PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
			out.flush();
			String clientMsg=in.readLine();
			System.out.println("客户端说:"+clientMsg);
			out.println("你好客户端:我是服务器,你的消息已经收到!");
		} catch (IOException e) {		
			e.printStackTrace();
		}finally{
		}

客户端:

 Socket socket=null;
		PrintWriter out=null;
		BufferedReader reader=null;
		try {
			socket = new Socket("127.0.0.1",9000);
			out = new PrintWriter(socket.getOutputStream(),true);
                        //print和write 重写了抽象类Writer里面的write方法
			out.println("你好服务器:我是客户端");
			out.flush();
			reader = new BufferedReader(
					new InputStreamReader(socket.getInputStream()));
			String serverMsg=reader.readLine();
			System.out.println("服务器回话:"+serverMsg);
		} catch (Exception e) {		
				e.printStackTrace();
		} finally{
			try {
				out.close();	
				reader.close();	
				socket.close();
			} 
			catch (IOException e) 
			{e.printStackTrace();	}	
		}	

模拟聊天:
服务器:

   try {
			ServerSocket serverSocket= new ServerSocket(9000);
			Socket socket = serverSocket.accept();
			BufferedReader  br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			Scanner sc = new Scanner(System.in);
			PrintWriter printWriter =new PrintWriter(socket.getOutputStream(),true);
			while(true){
			String s =	br.readLine();
			System.out.println("客户端说:"+s);
			if(s.contains("借钱")){
				printWriter.println("你被拉入黑名单");
				break;
			}
			String next = sc.next();
			printWriter.println(next);
			printWriter.flush();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

客户端:

  try {
			Socket s=new Socket("127.0.0.1",9000);
			PrintWriter pw =  new PrintWriter(s.getOutputStream(),true);
			Scanner sc = new Scanner(System.in);
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(s.getInputStream()));
            while(true){
                 String next = sc.next();
            	 pw.println(next);
                 pw.flush();
                 String s1 = bufferedReader.readLine();
                 System.out.println("服务器说:"+s1);
             	if(s1.contains("黑名单")){
             		break;
             	}
            }
          
         } catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

UDP程序原理

客户端:
1) 创建客户端 DatagramSocket 类 + 指定的发送端口
2) 准备数据 以字节数组的形式
3) 打包 DatagramPacket+服务器端的地址和端口
4) 发送
5) 释放资源
服务器端
1) 创建服务端 DatagramSocket 类 + 指定的接收端口
2) 准备接收数据的容器 以字节数组的形式封装为DatagramPacket
3) 包 接收数据
4) 分析
5) 释放资源
主要类及方法:
DatagramSocket类主要用于实现信息的发送和接收 。主要方法如下:
public DatagramSocket()
构造DatagramSocket对象,不指定监听的端口
public DatagramSocket(int port)
构造DatagramSocket对象,同时指定监听的端口
public void send (DatagramPacket p)
发送数据报
public void receive(DatagramPacket p)
接收数据报
DatagramPacket类用于包装需要发送或接收的信息
public DatagramPacket(byte[] buf,int length)
用来接收长度为 length 的数据包,length 参数必须小于等于 buf.length
public DatagramPacket(byte[]
buf,int length,InetAddress
address,int port)
构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号
public byte[] getData()
返回接收数据
public int getLength()
返回要发送或接收数据的长度
具体代码实现:
示例代码:
服务器端:

DatagramSocket ds = null;
		byte[] buf = new byte[1024];
		try {
			ds = new DatagramSocket();
			String info = "hello qy71.......";
			DatagramPacket dp= new DatagramPacket(info.getBytes(), info.getBytes().length,
					InetAddress.getByName("localhost"), 3000);
			ds.send(dp);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			ds.close();
		}

客户端:

 DatagramSocket ds = null;
		byte[] buf = new byte[1024];
		try {
			ds = new DatagramSocket(3000);
			DatagramPacket dp  = new DatagramPacket(buf,1024);
			ds.receive(dp);
			String str = new String(buf,0,dp.getLength());
			System.out.println("收到消息:"+str);
		}catch(Exception e){
		              e.printStackTrace();
		}finally{
			ds.close();
		}

注意事项:先启动客户端,receive方法在接收到数据报前一直阻塞。再运行服务器端。
总结:
TCP和UDP是Java网络编程中的传输方式。TCP提供两台计算机之间可靠无差错的数据传输,但资源消耗较大,性能和效率较低;UDP不保证可靠数据的传输,但资源消耗小,性能和效率较高。在实际网络编程中建议根据系统的特点和需要,具体选择合适的方式

相关标签: socket编程