NIO多端口监听

1、NIOServerTest.java

package com.neohope.multisocket;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

public class NIOServerTest {
    public static void StartSockets() throws IOException {
        Selector selector = Selector.open();

        int[] ports = {4000, 4001, 4002};
        for (int port : ports) {
            ServerSocketChannel server = ServerSocketChannel.open();
            server.configureBlocking(false);
            server.socket().bind(new InetSocketAddress(port));
            //只处理了建立连接的消息
            server.register(selector, SelectionKey.OP_ACCEPT);
        }

        int serverPort = 0;
        ByteBuffer byteBuffer = null;
        ServerSocketChannel serverChannel = null;
        SocketChannel clientChannel = null;
        while (selector.isOpen()) {
            selector.select();
            Set<SelectionKey> readyKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = readyKeys.iterator();
            while (keyIterator.hasNext()) {
                SelectionKey selectedKey = keyIterator.next();
                keyIterator.remove();
                if (selectedKey.isAcceptable()) {
                    serverChannel = (ServerSocketChannel) selectedKey.channel();
                    serverPort = serverChannel.socket().getLocalPort();
                    clientChannel = serverChannel.accept();
                    clientChannel.configureBlocking(false);
                    switch (serverPort) {
                        case 4000:
                            byteBuffer=ByteBuffer.wrap("welcome to port 4000".getBytes(Charset.forName("UTF-8")));
                            clientChannel.write(byteBuffer);
                            break;
                        case 4001:
                            byteBuffer=ByteBuffer.wrap("welcome to port 4001".getBytes(Charset.forName("UTF-8")));
                            clientChannel.write(byteBuffer);
                            break;
                        case 4002:
                            byteBuffer=ByteBuffer.wrap("welcome to port 4002".getBytes(Charset.forName("UTF-8")));
                            clientChannel.write(byteBuffer);
                            break;
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        StartSockets();
    }
}

2、NIOClientTest.java

package com.neohope.multisocket;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class NIOClientTest {
    public static void StartClient(String host, int port)
    {
        int readSize = 0;
        SocketChannel clientChannel = null;
        SocketAddress socketAddress = new InetSocketAddress(host, port);
        byte[] bytes;
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            clientChannel = SocketChannel.open();
            clientChannel.connect(socketAddress);
            try {
                while ((readSize = clientChannel.read(byteBuffer)) >= 0) {
                    byteBuffer.flip();
                    bytes = new byte[readSize];
                    byteBuffer.get(bytes);
                    byteArrayOutputStream.write(bytes);
                    byteBuffer.clear();
                    //服务端没有主动关闭连接,读取少于1024,假设读取完毕
                    if(readSize<1024)break;
                }
                System.out.println(byteArrayOutputStream.toString());
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    byteArrayOutputStream.close();
                } catch(Exception ex) {}
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                clientChannel.close();
            } catch(Exception ex) {}
        }
    }

    public static void main(String[] args) throws IOException {
        StartClient("localhost",4000);
        StartClient("localhost",4001);
        StartClient("localhost",4002);
    }
}

SSLSocket C# Part1

1、SSLSocket Server

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;

namespace SSLSocket
{
    class SSLSocketServer
    {
        static X509Certificate serverCertificate = null;
        static String delimiter = "=========================================================";

        public static void RunServer(String ip,int port,String p12Path)
        {
            serverCertificate = new X509Certificate2(p12Path, "sslTestPwd");

            TcpListener listener = new TcpListener(IPAddress.Parse(ip), port);
            listener.Start();
            while (true)
            {
                try
                {
                    TcpClient client = listener.AcceptTcpClient();
                    ProcessClient(client);
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }

        static void ProcessClient(TcpClient client)
        {
            SslStream sslStream = new SslStream(client.GetStream(), false);
            try
            {
                //sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls | SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.None, true);
                sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Ssl2 | SslProtocols.Ssl3, true);
                DisplaySecurityLevel(sslStream);
                DisplayCertificateInformation(sslStream);

                sslStream.ReadTimeout = 5000;
                sslStream.WriteTimeout = 5000;
                string messageData = ReadMessage(sslStream);
                Console.WriteLine(delimiter);
                Console.WriteLine("收到信息: {0}", messageData);
                Console.WriteLine(delimiter);
                //byte[] message = Encoding.UTF8.GetBytes("Hello from the server.");
                //Console.WriteLine("Sending hello message.");
                //sslStream.Write(message);
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                }
                Console.WriteLine("Authentication failed - closing the connection.");
                sslStream.Close();
                client.Close();
                return;
            }
            finally
            {
                sslStream.Close();
                client.Close();
            }
        }

        static string ReadMessage(SslStream sslStream)
        {
            byte[] buffer = new byte[2048];
            StringBuilder messageData = new StringBuilder();
            int bytes = -1;
            do
            {
                bytes = sslStream.Read(buffer, 0, buffer.Length);
                Decoder decoder = Encoding.UTF8.GetDecoder();
                char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                decoder.GetChars(buffer, 0, bytes, chars, 0);
                messageData.Append(chars);
                if (messageData.ToString().IndexOf("") != -1)
                {
                    break;
                }
            }
            while (bytes != 0);

            return messageData.ToString();
        }

        static void DisplaySecurityLevel(SslStream stream)
        {
            Console.WriteLine(delimiter);
            Console.WriteLine("通讯协议: {0}", stream.SslProtocol);
            Console.WriteLine("加密算法: {0} strength {1}", stream.CipherAlgorithm, stream.CipherStrength);
            Console.WriteLine("哈希算法: {0} strength {1}", stream.HashAlgorithm, stream.HashStrength);
            Console.WriteLine("密钥交换算法: {0} strength {1}", stream.KeyExchangeAlgorithm, stream.KeyExchangeStrength);
            Console.WriteLine(delimiter);
        }

        static void DisplayCertificateInformation(SslStream stream)
        {
            Console.WriteLine(delimiter);
            Console.WriteLine("证书吊销列表检查: {0}", stream.CheckCertRevocationStatus);

            X509Certificate localCertificate = stream.LocalCertificate;
            if (stream.LocalCertificate != null)
            {
                Console.WriteLine("本地证书签发者: {0}", localCertificate.Subject);
                Console.WriteLine("本地证书有效期: {0}~{1}", localCertificate.GetEffectiveDateString(),
                    localCertificate.GetExpirationDateString());
            }
            else
            {
                Console.WriteLine("本地证书为空");
            }

            X509Certificate remoteCertificate = stream.RemoteCertificate;
            if (stream.RemoteCertificate != null)
            {
                Console.WriteLine("远程证书签发者: {0}", remoteCertificate.Subject);
                Console.WriteLine("远程证书有效期: {0}至{1}", remoteCertificate.GetEffectiveDateString(),
                    remoteCertificate.GetExpirationDateString());
            }
            else
            {
                Console.WriteLine("远程证书为空");
            }
            Console.WriteLine(delimiter);
        }

    }
}

2、SSLSocket Client

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;

namespace SSLSocketClient
{
    class SSLSocketClient
    {
        //回调函数验证证书
        public static bool ValidateServerCertificate(
              object sender,
              X509Certificate certificate,
              X509Chain chain,
              SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
            {
                return true;
            }

            if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch || sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
            {
                return true;
            }

            return false;
        }

        public static void SendMessage(string ip, int port,String certPath, String msg)
        {
            TcpClient client = new TcpClient(ip, port);
            SslStream sslStream = new SslStream(client.GetStream(),
                false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);

            X509CertificateCollection certs = new X509CertificateCollection();
            X509Certificate cert = X509Certificate.CreateFromCertFile(certPath);
            certs.Add(cert);

            try
            {
                sslStream.AuthenticateAsClient("AtlasTiger", certs, SslProtocols.Tls, false);
                //sslStream.AuthenticateAsClient("AtlasTiger", certs, SslProtocols.Ssl3, false);

                //sslStream.AuthenticateAsClient("AtlasTiger", certs, SslProtocols.Ssl2, false);
                //sslStream.AuthenticateAsClient("AtlasTiger", certs, SslProtocols.None, false);
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Authentication failed : " + e);
                client.Close();
                return;
            }

            byte[] messsage = Encoding.UTF8.GetBytes(msg);
            sslStream.Write(messsage);
            sslStream.Flush();

            client.Close();
        }
    }
}

SSLSocket Java Part3

1、SSLSocket Client绕过证书检查

package com.ats.ssl.socket;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.KeyManager;
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;

public class ClientWithTrustManager {
	
	public static void connectAndSend(String trustStorePath,
			String trustStorePwd, String ip, int port, String msg) throws IOException, NoSuchAlgorithmException, KeyManagementException{
        
		SSLContext sslContext = SSLContext.getInstance("TLS");
		//SSLContext sslContext = SSLContext.getInstance("SSLv3");
		sslContext.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom());
		SSLContext.setDefault(sslContext);
		
		SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();  
		SSLSocket sslsocket = (SSLSocket) sslSocketFactory.createSocket(
				"localhost", 9999);

		try {
			OutputStream outputstream = sslsocket.getOutputStream();
			OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
					outputstream);
			BufferedWriter bufferedwriter = new BufferedWriter(
					outputstreamwriter);

			bufferedwriter.write(msg);
			bufferedwriter.flush();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			sslsocket.close();
		}
	}

	private static class DefaultTrustManager implements X509TrustManager {

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

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

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	}
	
	public static void main(String[] args) throws Exception {
		try {
			URL url = Server.class.getClassLoader().getResource(
					"myTrustStore.jks");
			String jks = url.getFile();

			connectAndSend(jks, "sslTestPwd", "127.0.0.1", 9999,
					"This msg is from Java SSL Client :)");

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

SSLSocket Java Part2

1、SSLSocket Java Server使用SSLContext

package com.ats.ssl.socket;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class ServerWithContext {

	static String delimiter = "=========================================================";

	public static void startListen(String keyStorePath, String keyStorePwd, int port) throws IOException, KeyStoreException, NoSuchAlgorithmException,
			CertificateException, UnrecoverableKeyException, KeyManagementException {

		KeyStore keyStore = KeyStore.getInstance("JKS");
		keyStore.load(new FileInputStream(keyStorePath), keyStorePwd.toCharArray());
		KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
		keyManagerFactory.init(keyStore, keyStorePwd.toCharArray());

		//SSLContext sslContext = SSLContext.getInstance("TLSv1");
		SSLContext sslContext = SSLContext.getInstance("SSLv3");
		sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[0], null);

		SSLServerSocketFactory sslserversocketfactory = sslContext.getServerSocketFactory();
		SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port);

		while (true) {
			SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

			DisplaySecurityLevel(sslsocket);
			DisplayCertificateInformation(sslsocket);

			try {
				InputStream inputstream = sslsocket.getInputStream();
				InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
				BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

				System.out.println(delimiter);
				String string = null;
				while ((string = bufferedreader.readLine()) != null) {
					System.out.println(string);
					System.out.flush();
				}
				System.out.println(delimiter);
			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				sslsocket.close();
			}
		}
	}

	static void DisplaySecurityLevel(SSLSocket sslsocket) {
		System.out.println(delimiter);
		SSLSession session = sslsocket.getSession();
		System.out.println("通讯协议: " + session.getProtocol());
		System.out.println("加密方式: " + session.getCipherSuite());
		System.out.println(delimiter);
	}

	static void DisplayCertificateInformation(SSLSocket sslsocket) {
		System.out.println(delimiter);
		Certificate[] localCertificates = sslsocket.getSession().getLocalCertificates();
		if (localCertificates == null || localCertificates.length == 0) {
			System.out.println("本地证书为空");
		} else {
			Certificate cert = localCertificates[0];
			System.out.println("本地证书类型: " + cert.getType());
			if (cert.getType().equals("X.509")) {
				X509Certificate x509 = (X509Certificate) cert;
				System.out.println("本地证书签发者: " + x509.getIssuerDN());
				System.out.println("本地证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
			}
		}

		try {
			Certificate[] peerCertificates = sslsocket.getSession().getPeerCertificates();

			if (peerCertificates == null || peerCertificates.length == 0) {
				System.out.println("远程证书为空");
			} else {
				Certificate cert = peerCertificates[0];
				System.out.println("远程证书类型: " + cert.getType());
				if (cert.getType().equals("X.509")) {
					X509Certificate x509 = (X509Certificate) cert;
					System.out.println("远程证书签发者: " + x509.getIssuerDN());
					System.out.println("远程证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
				}
			}
		} catch (SSLPeerUnverifiedException e) {
			// e.printStackTrace();
			System.out.println("远程证书为空");
		}

		System.out.println(delimiter);
	}

	public static void main(String[] arstring) {
		try {
			URL url = ServerWithContext.class.getClassLoader().getResource("myKeyStore.jks");
			String jks = url.getFile();
			startListen(jks, "sslTestPwd", 9999);

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

2、SSLSocket Java Client使用SSLContext

package com.ats.ssl.socket;

import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

public class ClientWithContext {
	
	public static void connectAndSend(String trustStorePath,
			String trustStorePwd, String ip, int port, String msg) throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException, UnrecoverableKeyException{
	
		KeyStore trustStore = KeyStore.getInstance("JKS");
		trustStore.load(new FileInputStream(trustStorePath), trustStorePwd.toCharArray());
		TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
		trustManagerFactory.init(trustStore);
        
		SSLContext sslContext = SSLContext.getInstance("TLSv1");
		//SSLContext sslContext = SSLContext.getInstance("SSLv3");
		
		sslContext.init(new KeyManager[0], trustManagerFactory.getTrustManagers(), null);
		SSLContext.setDefault(sslContext);
		
		SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();  
		SSLSocket sslsocket = (SSLSocket) sslSocketFactory.createSocket(
				"localhost", 9999);

		try {
			OutputStream outputstream = sslsocket.getOutputStream();
			OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
					outputstream);
			BufferedWriter bufferedwriter = new BufferedWriter(
					outputstreamwriter);

			bufferedwriter.write(msg);
			bufferedwriter.flush();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			sslsocket.close();
		}
	}

	public static void main(String[] args) throws Exception {
		try {
			URL url = Server.class.getClassLoader().getResource(
					"myTrustStore.jks");
			String jks = url.getFile();

			connectAndSend(jks, "sslTestPwd", "127.0.0.1", 9999,
					"This msg is from Java SSL Client :)");

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

SSLSocket Java Part1

1、使用环境变量,最基本的SSLSocket Server

package com.ats.ssl.socket;

import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;

public class Server {

	static String delimiter = "=========================================================";

	public static void startListen(String keyStorePath, String keyStorePwd, int port) throws IOException {
		System.setProperty("javax.net.ssl.keyStore", keyStorePath);
		System.setProperty("javax.net.ssl.keyStorePassword", keyStorePwd);

		SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
		SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port);

		while (true) {
			SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

			String protocols[] = { "TLSv1" };
			// String protocols[] = {"SSLv2Hello","TLSv1","SSLv3"};
			// String protocols[] = {"SSLv3"};
			sslsocket.setEnabledProtocols(protocols);

			DisplaySecurityLevel(sslsocket);
			DisplayCertificateInformation(sslsocket);

			try {
				InputStream inputstream = sslsocket.getInputStream();
				InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
				BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

				System.out.println(delimiter);
				String string = null;
				while ((string = bufferedreader.readLine()) != null) {
					System.out.println(string);
					System.out.flush();
				}
				System.out.println(delimiter);
			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				sslsocket.close();
			}
		}
	}

	static void DisplaySecurityLevel(SSLSocket sslsocket) {
		System.out.println(delimiter);
		SSLSession session = sslsocket.getSession();
		System.out.println("通讯协议: " + session.getProtocol());
		System.out.println("加密方式: "+session.getCipherSuite());
		System.out.println(delimiter);
	}

	static void DisplayCertificateInformation(SSLSocket sslsocket) {
		System.out.println(delimiter);
		Certificate[] localCertificates = sslsocket.getSession().getLocalCertificates();
		if (localCertificates == null || localCertificates.length == 0) {
			System.out.println("本地证书为空");
		} else {
			Certificate cert = localCertificates[0];
			System.out.println("本地证书类型: " + cert.getType());
			if (cert.getType().equals("X.509")) {
				X509Certificate x509 = (X509Certificate) cert;
				System.out.println("本地证书签发者: " + x509.getIssuerDN());
				System.out.println("本地证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
			}
		}

		try {
			Certificate[] peerCertificates = sslsocket.getSession().getPeerCertificates();

			if (peerCertificates == null || peerCertificates.length == 0) {
				System.out.println("远程证书为空");
			} else {
				Certificate cert = peerCertificates[0];
				System.out.println("远程证书类型: " + cert.getType());
				if (cert.getType().equals("X.509")) {
					X509Certificate x509 = (X509Certificate) cert;
					System.out.println("远程证书签发者: " + x509.getIssuerDN());
					System.out.println("远程证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
				}
			}
		} catch (SSLPeerUnverifiedException e) {
			// e.printStackTrace();
			System.out.println("远程证书为空");
		}

		System.out.println(delimiter);
	}

	public static void main(String[] arstring) {
		try {
			URL url = Server.class.getClassLoader().getResource("myKeyStore.jks");
			String jks = url.getFile();
			startListen(jks, "sslTestPwd", 9999);

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

2、相应的,使用环境变量进行设置的,SSLSocket Client

package com.ats.ssl.socket;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.net.URL;

public class Client {
	public static void connectAndSend(String trustStorePath,
			String trustStorePwd, String ip, int port, String msg)
			throws IOException {
		System.setProperty("javax.net.ssl.trustStore", trustStorePath);
		System.setProperty("javax.net.ssl.trustStorePassword", trustStorePwd);

		SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
				.getDefault();
		SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
				"localhost", 9999);

		//String protocols[] = {"TLSv1"};
		String protocols[] = {"SSLv2Hello","TLSv1","SSLv3"};
		//String protocols[] = {"SSLv3"};
		sslsocket.setEnabledProtocols(protocols);

		try {
			OutputStream outputstream = sslsocket.getOutputStream();
			OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
					outputstream);
			BufferedWriter bufferedwriter = new BufferedWriter(
					outputstreamwriter);

			bufferedwriter.write(msg);
			bufferedwriter.flush();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			sslsocket.close();
		}
	}

	public static void main(String[] arstring) {
		try {
			URL url = Server.class.getClassLoader().getResource(
					"myTrustStore.jks");
			String jks = url.getFile();

			connectAndSend(jks, "sslTestPwd", "127.0.0.1", 9999,
					"This msg is from Java SSL Client :)");

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

MinGW中Socket基础

1.客户端简单例子
myc.c

#define MINGW32

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef MINGW32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#endif

#define MAXLINE 1024

int main(int argc,char **argv) 
{
  int  sockfd,n;
  char  receline[MAXLINE+1];
  struct  sockaddr_in serveraddr;

  //输入参数太少,退出
  if(argc != 2) 
  { 
    printf("Usage :%s  IP_address\n", argv[0]);
    exit(0);
  }

  #ifdef MINGW32
  //Winsows下启用socket
  WSADATA wsadata;
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail\n");
    exit(0);
  }
  #endif
  
  //建立socket
  if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
  {
    printf("socket() fail\n");
    exit(0);
  }

  //设置协议及Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_port=htons(1024);

  //设置IP
  serveraddr.sin_addr.s_addr=inet_addr(argv[1]);

  //连接
  if(connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr))==-1)
  {
    printf("connect() fail\n");
    exit(0);
  }

  //读取数据并输入到标准输出
  #ifdef MINGW32
  while((n=recv(sockfd,receline,MAXLINE,0))>0)
  #else
  while((n=read(sockfd,receline,MAXLINE))>0)
  #endif
  { 
    receline[n]=0;
    if(fputs(receline,stdout)==EOF)
    {
      printf("fputs() error\r\n");
    }
  }

  //没有获取数据
  if(n<0) 
  {
    printf("read() fail\n");
  }

  #ifdef MINGW32
  //Winsows下关闭socket
  closesocket(sockfd);
  WSACleanup();
  #endif

  exit(0);
}
&#91;/code&#93;

2.服务端简单例子
mys.c
&#91;code lang="c"&#93;
#define MINGW32

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef MINGW32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#endif

#define LISTENQ 10

int main(int argc,char *argv[])
{
  int  serverfd,connectfd;
  struct  sockaddr_in serveraddr;
  char  buff[1024];
  time_t  tlick;
  int  iRet;

  #ifdef MINGW32
  //Winsows下启用socket
  WSADATA wsadata;
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail\n");
    exit(0);
  }
  #endif

  //新建socket
  printf("socket()\n");
  serverfd=socket(AF_INET,SOCK_STREAM,0);
  if(serverfd==-1)
  {
    printf("socket() fail\n");
    exit(0);
  }

  //清零
  memset(&serveraddr,0,sizeof(serveraddr));

  //设置协议
  serveraddr.sin_family=AF_INET;
  //设置IP
  serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  //设置Port
  serveraddr.sin_port=htons(1024);

  //绑定端口,监听1024端口的任何请求
  printf("bind()\n");
  iRet=bind(serverfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
  if(iRet==-1)
  {
    printf("bind() fail\n");
    exit(0);
  }

  //监听端口,最大并发数10
  printf("listen()\n");
  iRet=listen(serverfd,LISTENQ);
  if(iRet==-1)
  {
    printf("listen() fail\n");
    exit(0);
  }

  //接受请求,发送主机时间
  for(;;)
  {
    printf("Waiting for connection...\n");
    //接受请求
    connectfd=accept(serverfd,(struct sockaddr*)NULL,NULL);
    //获取时间    
    tlick=time(NULL);
    //格式化时间    
    snprintf(buff,sizeof(buff),"From mys:\n%s",ctime(&tlick));
    //写入时间
    //关闭请求
    #ifdef MINGW32
    send(connectfd,buff,strlen(buff),0);
    closesocket(connectfd);
    #else
    write(connectfd,buff,strlen(buff));
    close(connectfd);
    #endif
  }

  #ifdef MINGW32
  //Winsows下关闭socket
  closesocket(serverfd);
  WSACleanup();
  #endif

  //退出
  exit(0);
}

3.Makefile

all:mys myc

mys:mys.c
	gcc -g -o mys mys.c -l wsock32

myc:myc.c
	gcc -g -o myc myc.c -l wsock32

clean:
	del *~ *.o *.exe

VC中Socket通信基础

1.客户端程序
SocketClientBlock.c

#pragma comment(lib, "WS2_32")

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#define BUF_SIZE (1024)

int main(int argc,char **argv) 
{
  WSADATA wsadata;

  int  sockfd,n;
  char  receline[BUF_SIZE];
  struct  sockaddr_in serveraddr;

  //Winsows下启用socket
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail\n");
    exit(0);
  }

  //建立socket
  if((sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
  {
    printf("socket() fail\n");
    exit(0);
  }

  //设置协议,IP及Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_port=htons(1024);
  serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1");
  /*
  //hostname转ip
  hostent *hostEnt = gethostbyname( strRemote );
  if( hostEnt != NULL )
  {
    lIPAddress = ((in_addr*)hostEnt->h_addr)->s_addr;
    serveraddr.sin_addr.s_addr = lIPAddress;
  }
  else
  {
    serveraddr.sin_addr.s_addr = inet_addr( strRemote );
  }
  */

  //连接
  if(connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr))==SOCKET_ERROR)
  {
    printf("connect() fail\n");
    exit(0);
  }

  //读取数据并输入到标准输出
  while((n=recv(sockfd,receline,BUF_SIZE,0))!=SOCKET_ERROR)
  { 
    receline[n]=0;
    if(fputs(receline,stdout)==EOF)
    {
      printf("fputs() error\r\n");
    }
  }

  //没有获取数据
  if(n<0) 
  {
    printf("read() fail\n");
  }

  //Winsows下关闭socket
  closesocket(sockfd);
  WSACleanup();

  exit(0);
}
&#91;/code&#93;

2.服务端程序,阻塞
SocketServerBlock.c
&#91;code lang="c"&#93;
#pragma comment(lib, "WS2_32")

#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_CONNECT_NUM (10)

int main(int argc,char** argv)
{
  WSADATA wsadata;
  struct  sockaddr_in serveraddr;
  int  socketflag,connectflag;

  time_t  time_tick;
  char  buff[1024];
  
  //Winsows下启用网络
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail,%d\n", WSAGetLastError());
    exit(0);
  }
  
  //新建socket
  if(INVALID_SOCKET==(socketflag=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))
  {
    printf("socket() fail\n");
    exit(0);
  }

  //清零,设置协议,设置IP,设置Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family=AF_INET;
  serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  serveraddr.sin_port=htons(1024);

  //绑定端口,监听1024端口的任何请求
  if(SOCKET_ERROR==bind(socketflag,(struct sockaddr*)&serveraddr,sizeof(serveraddr)))
  {
    printf("bind() fail\n");
    exit(0);
  }

  //监听端口,最大并发数MAX_CONNECT_NUM
  if(SOCKET_ERROR==listen(socketflag,MAX_CONNECT_NUM))
  {
    printf("listen() fail\n");
    exit(0);
  }

  //接受请求,发送主机时间
  for(;;)
  {
    struct  sockaddr clientaddr;
    int iLen = sizeof(clientaddr);
    printf("Waiting for connection...\n");

    //接受连接
    connectflag=accept(socketflag,&clientaddr,&iLen);
    if(INVALID_SOCKET==connectflag)
    {
      printf("accept() fail\n");
      exit(0);
    }

    //获取时间,并格式化
    time_tick=time(NULL);
    sprintf(buff,"From mys:\n%s",ctime(&time_tick));
    //写入时间
    if(SOCKET_ERROR==send(connectflag,buff,strlen(buff),0))
    {
      printf("send() fail\n");
      exit(0);
    }

    //关闭连接
    closesocket(connectflag);
  }

  //Winsows下关闭socket及网络
  if(SOCKET_ERROR==closesocket(socketflag))
  {
    printf("closesocket() fail\n");
    exit(0);
  }
  WSACleanup();

  //退出
  exit(0);
}

3.服务端程序,阻塞,有Select
SocketServerBlockSelect.c

#pragma comment(lib, "WS2_32")

#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_CONNECT_NUM (10)

int main(int argc,char** argv)
{
  WSADATA wsadata;
  struct  sockaddr_in serveraddr;
  int  socketflag,connectflag;

  fd_set  fdR;
  struct  timeval timeout ={1,500};

  time_t  time_tick;
  char  buff[1024];
  
  //Winsows下启用网络
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail,%d\n", WSAGetLastError());
    exit(0);
  }
  
  //新建socket
  if(INVALID_SOCKET==(socketflag=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))
  {
    printf("socket() fail\n");
    exit(0);
  }

  //清零,设置协议,设置IP,设置Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family=AF_INET;
  serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  serveraddr.sin_port=htons(1024);

  //绑定端口,监听1024端口的任何请求
  if(SOCKET_ERROR==bind(socketflag,(struct sockaddr*)&serveraddr,sizeof(serveraddr)))
  {
    printf("bind() fail\n");
    exit(0);
  }

  //监听端口,最大并发数MAX_CONNECT_NUM
  if(SOCKET_ERROR==listen(socketflag,MAX_CONNECT_NUM))
  {
    printf("listen() fail\n");
    exit(0);
  }

  //接受请求,发送主机时间
  for(;;)
  {
    printf("Waiting for connection...\n");

    FD_ZERO(&fdR);
    FD_SET(socketflag, &fdR);
        switch (select(0, &fdR, NULL, NULL,&timeout)) 
    {
    case SOCKET_ERROR:
      printf("Socket Error...\n");
      break;
    case 0:
      printf("Time Out Here...\n");
      break;
    default:
      printf("Connection is coming...\n");
      if (1)
      {
        struct  sockaddr clientaddr;
        int iLen = sizeof(clientaddr);

        //接受连接
        connectflag=accept(socketflag,&clientaddr,&iLen);
        if(INVALID_SOCKET==connectflag)
        {
          printf("accept() fail\n");
          exit(0);
        }

        //获取时间,并格式化
        time_tick=time(NULL);
        sprintf(buff,"From mys:\n%s",ctime(&time_tick));
        //写入时间
        if(SOCKET_ERROR==send(connectflag,buff,strlen(buff),0))
        {
          printf("send() fail\n");
          exit(0);
        }

        //关闭连接
        closesocket(connectflag);
      }
      break;
        }
  }

  //Winsows下关闭socket及网络
  if(SOCKET_ERROR==closesocket(socketflag))
  {
    printf("closesocket() fail\n");
    exit(0);
  }
  WSACleanup();

  //退出
  exit(0);
}

4.服务端程序,非阻塞
SocketServerNonBlock.c

#pragma comment(lib, "WS2_32")

#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_CONNECT_NUM (10)

int main(int argc,char** argv)
{
  WSADATA wsadata;
  struct  sockaddr_in serveraddr;
  int  socketflag,connectflag;

  time_t  time_tick;
  char  buff[1024];

  unsigned long flag=1;
  
  //Winsows下启用网络
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail,%d\n", WSAGetLastError());
    exit(0);
  }
  
  //新建socket
  if(INVALID_SOCKET==(socketflag=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))
  {
    printf("socket() fail\n");
    exit(0);
  }

  //非阻塞方式
  if(ioctlsocket(socketflag,FIONBIO,&flag)!=0)
  {
    printf("ioctlsocket() fail\n");
    exit(0);
  }

  //清零,设置协议,设置IP,设置Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family=AF_INET;
  serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  serveraddr.sin_port=htons(1024);

  //绑定端口,监听1024端口的任何请求
  if(SOCKET_ERROR==bind(socketflag,(struct sockaddr*)&serveraddr,sizeof(serveraddr)))
  {
    printf("bind() fail\n");
    exit(0);
  }

  //监听端口,最大并发数MAX_CONNECT_NUM
  if(SOCKET_ERROR==listen(socketflag,MAX_CONNECT_NUM))
  {
    printf("listen() fail\n");
    exit(0);
  }

  //接受请求,发送主机时间
  for(;;)
  {
    struct  sockaddr clientaddr;
    int iLen = sizeof(clientaddr);
    printf("Waiting for connection...\n");

    //接受连接
    connectflag=accept(socketflag,&clientaddr,&iLen);
    if(INVALID_SOCKET==connectflag)
    {
      printf("no connection\n");
      Sleep(1500);
    }
    else
    {
      printf("Connection is coming...\n");
      //获取时间,并格式化
      time_tick=time(NULL);
      sprintf(buff,"From mys:\n%s",ctime(&time_tick));
      //写入时间
      if(SOCKET_ERROR==send(connectflag,buff,strlen(buff),0))
      {
        printf("send() fail\n");
        exit(0);
      }

      //关闭连接
      closesocket(connectflag);
    }
  }

  //Winsows下关闭socket及网络
  if(SOCKET_ERROR==closesocket(socketflag))
  {
    printf("closesocket() fail\n");
    exit(0);
  }
  WSACleanup();

  //退出
  exit(0);
}