文档章节

Java之Socket

素人派
 素人派
发布于 2016/12/31 20:48
字数 1331
阅读 1
收藏 0
  • 介绍
网络编程是Java中很重要的一块,实现的是应用层的网络协议。本文介绍如何使用socket开发,包括有TCP和UDP的代码实现。 关于UDP广播相关的内容,可以点击这里查看另外一篇文章。 普通的Socket是使用明文来传输的,那怎么才能加密这个传输通道呢?赶快下面的例子吧。
  • TCP
下面的代码实现一个服务端监听,然后打印接收到的字符串数据,最后再给客户端返回一个字符串。 [codesyntax lang="java"]
/**
 * http://surenpi.com
 */
package org.suren.test;

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

/**
 * @author suren
 * @date 2015年9月2日 上午8:09:54
 */
public class TcpServer
{
	public static void main(String[] args) throws Exception
	{
		ServerSocket server = null;
		
		try
		{
			server = new ServerSocket(8090);
			
			while(true)
			{
				Socket client = server.accept();
				
				SocketAddress remoteAddr = client.getRemoteSocketAddress();
				InputStream input = client.getInputStream();
				OutputStream output = client.getOutputStream();
				
				System.out.println(remoteAddr);
				
				byte[] buf = new byte[1024];
				int length = -1;
				
				StringBuffer stringBuf = new StringBuffer();
				while((length = input.read(buf)) > 0)
				{
					stringBuf.append(new String(buf, 0, length));
					
					if(length < buf.length)
					{
						break;
					}
				}
				
				System.out.println(stringBuf.toString());
				
				output.write("done".getBytes());
				
				System.out.println("server round over.");
				
				client.close();
			}
		}
		finally
		{
			if(server != null)
			{
				server.close();
				
				System.out.println("server closed.");
			}
		}
	}
}
[/codesyntax] 下面是客户端的实现: [codesyntax lang="java"]
/**
 * http://surenpi.com
 */
package org.suren.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

/**
 * @author suren
 * @date 2015年9月2日 上午8:14:42
 */
public class TcpClient
{

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException
	{
		Socket client = new Socket();

		SocketAddress addr = new InetSocketAddress("127.0.0.1", 8090);
		
		client.connect(addr);
		
		InputStream input = client.getInputStream();
		OutputStream output = client.getOutputStream();
		
		output.write("hello from client".getBytes());
		
		byte[] buf = new byte[1024];
		int length = -1;
		
		System.out.println("client write over.");
		
		StringBuffer stringBuf = new StringBuffer();
		while((length = input.read(buf)) > 0)
		{
			stringBuf.append(new String(buf, 0, length));
			
			if(length < buf.length)
			{
				break;
			}
		}
		
		System.out.println(stringBuf.toString());
		
		client.close();
	}

}
[/codesyntax]
  • UDP
这里首先要提醒的是,UDP协议是不保证数据传输的完整性的,所以说如果对数据完整性要求很高的话,不建议采用这种协议。UDP相比TCP的优点是传输效率高,可以用在视频传输上。 [codesyntax lang="java"]
/**
 * http://surenpi.com
 */
package org.suren.test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * @author suren
 * @date 2015年9月2日 上午9:44:39
 */
public class UdpServer
{

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException
	{
		try(DatagramSocket server = new DatagramSocket(9999))
		{
			while(true)
			{
				int length = 1024;
				byte[] buf = new byte[length];
				DatagramPacket packet = new DatagramPacket(buf, length);
				
				server.receive(packet);
				
				System.out.println("receive from client.");
				
				buf = packet.getData();
				
				System.out.println(new String(buf, packet.getOffset(), packet.getLength()));

				packet.setData("server replly".getBytes());
				server.send(packet);
			}
		}
	}
}
[/codesyntax] 以下是客户端代码(理论上udp是没有客户端和服务端之分的,从下面的代码就可以看出来,客户端和服务端没什么区别): [codesyntax lang="java"]
/**
 * http://surenpi.com
 */
package org.suren.test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
 * @author suren
 * @date 2015年9月2日 上午9:51:40
 */
public class UdpClient
{
	public static void main(String[] args) throws IOException
	{
		try(DatagramSocket client = new DatagramSocket())
		{
			byte[] buf = "hello from udp client message.".getBytes();
			int length = buf.length;
			DatagramPacket packet = new DatagramPacket(buf, length);
			packet.setSocketAddress(new InetSocketAddress("localhost", 9999));
			
			client.send(packet);
			
			client.receive(packet);
			
			System.out.println(new String(packet.getData(), packet.getOffset(), packet.getLength()));
		}
	}
}
[/codesyntax]
  • 安全的TCP
上面介绍的TCP连接,发送的都是明文的数据,通过数据包拦截工具就可以完全看到发送和接收的内容。当然,我们可以通过把要发送的数据先做加密,然后再发送。这就需要自己来编写加密和解密的逻辑了,安全性完全在于你的加密算法。另外,我们还可以使用SSL的TCP连接来发送明文或者密文数据,这是一种可以和普通TCP连接无缝对接的方式——和上面的写法几乎完全一样,只是在获取Socket的方式上有所区别。 既然是一种安全的通讯方式,肯定少不了相应的机制了。我们这里需要 使用keytool工具来生成一个证书文件,下面的代码中会用到。 下面是服务端代码: [codesyntax lang="java"]
/**
 * http://surenpi.com
 */
package org.suren.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * @author suren
 * @date 2015年9月2日 上午10:11:54
 */
public class SSLTcpServer
{

	/**
	 * @param args
	 * @throws KeyStoreException 
	 * @throws IOException 
	 * @throws CertificateException 
	 * @throws NoSuchAlgorithmException 
	 * @throws UnrecoverableKeyException 
	 * @throws KeyManagementException 
	 */
	public static void main(String[] args) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException
	{
		//证书加载
		char[] pwd = "123456".toCharArray();
		KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
		
		try(InputStream input = new FileInputStream(new File("D:/suren")))
		{
			keyStore.load(input, pwd);
		}
		
		KeyManagerFactory keyMgr = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		keyMgr.init(keyStore, pwd);
		
		//初始化ssl上下文
	    X509TrustManager x509m = new X509TrustManager(){

			@Override
			public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException
			{
				System.out.println("checkClientTrusted");
			}

			@Override
			public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException
			{
				System.out.println("checkServerTrusted");
			}

			@Override
			public X509Certificate[] getAcceptedIssuers()
			{
				System.out.println("getAcceptedIssuers");
				return null;
			}
		};
	    
		SSLContext sslContext = SSLContext.getInstance("SSL");
		sslContext.init(keyMgr.getKeyManagers(),
				new TrustManager[]{x509m},
				new SecureRandom());
		
		SSLServerSocketFactory factory = sslContext.getServerSocketFactory();
		
		try(SSLServerSocket server = (SSLServerSocket) factory.createServerSocket(8900))
		{
			System.out.println("ssl server socket created.");
			
			while(true)
			{
				try(Socket client = server.accept())
				{
					InputStream input = client.getInputStream();
					OutputStream output = client.getOutputStream();
					
					StringBuffer strBuf = new StringBuffer();
					
					int length = 1024;
					byte[] buf = new byte[length];			
					
					while((length = input.read(buf)) > 0)
					{
						strBuf.append(new String(buf, 0, length));
						
						if(length < buf.length)
						{
							break;
						}
					}
					
					System.out.println(strBuf.toString());
					
					output.write("ssl server say done.".getBytes());
				}
			}
		}
	}
}
[/codesyntax] 下面是客户端代码: [codesyntax lang="java"]
/**
 * http://surenpi.com
 */
package org.suren.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * @author suren
 * @date 2015年9月2日 上午10:52:31
 */
public class SSLTcpClient
{

	/**
	 * @param args
	 * @throws IOException 
	 * @throws UnknownHostException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 * @throws KeyStoreException 
	 * @throws CertificateException 
	 * @throws UnrecoverableKeyException 
	 */
	public static void main(String[] args) throws UnknownHostException, IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException, UnrecoverableKeyException
	{
		SSLContext context = SSLContext.getInstance("SSL");
		context.init(null,
				new TrustManager[]{new X509TrustManager(){

					@Override
					public void checkClientTrusted(X509Certificate[] chain,
							String authType) throws CertificateException
					{
					}

					@Override
					public void checkServerTrusted(X509Certificate[] chain,
							String authType) throws CertificateException
					{
					}

					@Override
					public X509Certificate[] getAcceptedIssuers()
					{
						return null;
					}
				}},
				new SecureRandom());
		
		SSLSocketFactory factory = context.getSocketFactory();
		
		try(SSLSocket client = (SSLSocket) factory.createSocket("localhost", 8900))
		{
			InputStream input = client.getInputStream();
			OutputStream output = client.getOutputStream();
			
			output.write("from ssl client.".getBytes());
			
			StringBuffer strBuf = new StringBuffer();
			byte[] buf = new byte[1024];
			int len = -1;
			while((len = input.read(buf)) > 0)
			{
				strBuf.append(new String(buf, 0, len));
				
				if(len < buf.length)
				{
					break;
				}
			}
			
			System.out.println(strBuf);
		}
	}
}
[/codesyntax]
  • 参考
http://410063005.iteye.com/blog/1751243 http://www.ibm.com/developerworks/cn/java/j-lo-ssltls/

本文转载自:http://surenpi.com/2015/09/02/java%e4%b9%8bsocket/

素人派
粉丝 26
博文 1907
码字总数 10223
作品 6
东城
程序员
私信 提问

暂无文章

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部