- 浏览: 200368 次
- 性别:
- 来自: 湖南
文章分类
最新评论
-
kongyumi:
电话18800163600
初学certificate -
kongyumi:
解压密码多少?求告知
初学certificate -
船到桥头自然沉:
初学certificate -
笑海人胜:
...
JavaFX学习之Preloader -
kanjiantaiyang:
引用[img][/img][url][/url][b][/b] ...
security
创建证书
上面创建了X509Certificate,并且把私钥和证书用字符串保存起来,这里用的是apache的commons-codec.jar里面的Base64。
建立SSLServerSocket
建立SSLClientSocket
自定义X509KeyManager
自定义X509TrustManager,这里checkServerTrusted验证服务端证书。
这里既验证了服务端,也验证了客户端,前提是客户端的证书已经传输过去。
package com.ssl; import com.security.X509CertificateInfo; import com.util.KeyUtility; import com.util.StringUtility; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.codec.binary.Base64; import sun.security.x509.AlgorithmId; import sun.security.x509.CertificateAlgorithmId; import sun.security.x509.CertificateIssuerName; import sun.security.x509.CertificateSerialNumber; import sun.security.x509.CertificateSubjectName; import sun.security.x509.CertificateValidity; import sun.security.x509.CertificateVersion; import sun.security.x509.CertificateX509Key; import sun.security.x509.X500Name; import sun.security.x509.X500Signer; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertInfo; public class BuildCertificate { private String x509Certificate = "MIICRTCCAa6gAwIBAgIET8SU6DANBgkqhkiG9w0BAQQFADBnMRUwEwYDVQQKEwxPcmdhbml6YXRpb24xGTAXBgNVBAsTEE9yZ2FuaXphdGlvblVuaXQxETAPBgNVBAcTCExvY2FsaXR5MQ4wDAYDVQQIEwVzdGF0ZTEQMA4GA1UEAxMHY291bnRyeTAeFw0xMjA1MjkwOTIwNDBaFw0yMzEyMjIyMjE0MDBaMGcxFTATBgNVBAoTDE9yZ2FuaXphdGlvbjEZMBcGA1UECxMQT3JnYW5pemF0aW9uVW5pdDERMA8GA1UEBxMITG9jYWxpdHkxDjAMBgNVBAgTBXN0YXRlMRAwDgYDVQQDEwdjb3VudHJ5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUFhd0YhO9HFSEfQKDzKjN/EwKw7h4MxZaTvLqmhrSlkhN6p2rhHFePF0lWM4spVDTd285FYHrf3HOVl9Fm/5ChQeEqPNMBCkYgMDMEQhxKQ4Gpt/Nanf4awdoYYFwvP4Bj9kkMwLa9iAVstb4Y9idzTWVtjB8G5YT0CUeBi+y0wIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAHHySfSjsg8ogL/dPzF4eODkaYzBSIGHN03O5JEIRSzBpX5fXwPpJIuEX7g5NM8f4hv5wOgiAV8G7J9Bh1qGk6pv8QeYQBwSnEXyTDtekeTkWoyo8vP9VaJmQG9NhLQs4+3rnPtesIaMhLe3HTJ/+5bKKsg4SbC/cRlwWIQJ1Fob"; private String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJQWF3RiE70cVIR9AoPMqM38TArDuHgzFlpO8uqaGtKWSE3qnauEcV48XSVYziylUNN3bzkVget/cc5WX0Wb/kKFB4So80wEKRiAwMwRCHEpDgam381qd/hrB2hhgXC8/gGP2SQzAtr2IBWy1vhj2J3NNZW2MHwblhPQJR4GL7LTAgMBAAECgYBm/npvoqsR0zthLkTqgBRDt573uap6RyXbx58h1e6j2owNTQk+Oo5SuW8bQ4mZ+ZyehynfLPtAXFI97Uqz8kvCzuTPkOgD2Xt1f+vfD2y22VoBxh+Yp4U3dw/osDrK79WzD0fEdiW9mmtGzBSadYM8DmpBkR9pFYDVvCKgp3mf4QJBAM1PwrqefI9HFLBv0Xx3PS6H7rB/DG/GzQcaxGJRzx3B9GShYOmBw+CBsqt1wcpke0XlBF3OCQgsTBVeZE1F4cMCQQC4pYqCmx+GxPBj4m6LrBCLZiWe5pwybJDH+85k4Qpbt3AspTXphl73sJDZz9STgIQKw6RK80iPc4jU/GFAqkmxAkAQHjfiYLjUorbsFwsyI0ZJVeCWOJMoX0oPSbmrIlMJOgXOtKCgFFDlWilFrqv1EKhg11bdamRpINkkQFHNgzPzAkBXHMp/Gb5C79DV3vL2dEQN8DAZioTwiSW5I8RY9Y7UfHOwrHUF6n4Nb0C3cgTBXiVtiqWNMr/t5b0NdtBPGMfRAkEApxqnjmBZPWFjHHGWdqjYbru6WElVHvecNVLZRp0dScdqFArUg9V04hJPFP3Z/5sHo9d5v7nhzNeizbTkWGq6fQ=="; public KeyPair createKeyPair(int length) { KeyPair keyPair = null; try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(length, new SecureRandom()); keyPair = keyPairGenerator.generateKeyPair(); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(X509CertificateInfo.class.getName()).log(Level.SEVERE, null, ex); } return keyPair; } public Certificate createCertificate(KeyPair keyPair, String name) { try { X500Name x500Name = new X500Name(name); Signature signature = Signature.getInstance("MD5WithRSA"); X500Signer signer = new X500Signer(signature, x500Name); X509CertInfo x509CertInfo = new X509CertInfo(); x509CertInfo.set(X509CertInfo.VERSION, new CertificateVersion(2)); x509CertInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int) (System.currentTimeMillis() / 1000L))); AlgorithmId algorithmId = signer.getAlgorithmId(); x509CertInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithmId)); x509CertInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(x500Name)); x509CertInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic())); CertificateValidity interval = new CertificateValidity(new Date(), new Date(System.currentTimeMillis() + 365000000000L)); x509CertInfo.set(X509CertInfo.VALIDITY, interval); x509CertInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(signer.getSigner())); X509CertImpl x509CertImpl = new X509CertImpl(x509CertInfo); x509CertImpl.sign(keyPair.getPrivate(), "MD5WithRSA"); return x509CertImpl; } catch (InvalidKeyException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchProviderException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (SignatureException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (CertificateException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } return null; } public Certificate buildCert(String cert){ try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) cf.generateCertificate( new ByteArrayInputStream( Base64.decodeBase64(cert) ) ); return certificate; } catch (CertificateException ex) { Logger.getLogger(KeyUtility.class.getName()).log(Level.SEVERE, null, ex); } return null; } public PrivateKey buildKey(String key){ KeyFactory kf; try { kf = KeyFactory.getInstance("RSA"); PrivateKey privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(key))); return privateKey; } catch (InvalidKeySpecException ex) { Logger.getLogger(KeyUtility.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(KeyUtility.class.getName()).log(Level.SEVERE, null, ex); } return null; } public static void main(String args[]) { try { BuildCertificate buildCertificate = new BuildCertificate(); KeyPair keyPair = buildCertificate.createKeyPair(1024); X509Certificate x509Cert = (X509Certificate) buildCertificate.createCertificate(keyPair, "CN=country,ST=state,L=Locality,OU=OrganizationUnit,O=Organization"); byte[] bytes = x509Cert.getEncoded(); String cert = Base64.encodeBase64String(bytes); String privateKey = Base64.encodeBase64String(keyPair.getPrivate().getEncoded()); buildCertificate.setPrivateKey(privateKey); buildCertificate.setX509Certificate(cert); System.out.println(cert); System.out.println(privateKey); } catch (CertificateEncodingException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } } public String getPrivateKey() { return privateKey; } public String getX509Certificate() { return x509Certificate; } public void setPrivateKey(String privateKey) { this.privateKey = privateKey; } public void setX509Certificate(String x509Certificate) { this.x509Certificate = x509Certificate; } }
上面创建了X509Certificate,并且把私钥和证书用字符串保存起来,这里用的是apache的commons-codec.jar里面的Base64。
package com.ssl; import com.security.SSLKeyManager; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; public class SSLServer { public void sslServerSocket() { try { SSLContext sslc = SSLContext.getInstance("SSL"); BuildCertificate buildCertificate = new BuildCertificate(); String pk = buildCertificate.getPrivateKey(); String x509Cert = buildCertificate.getX509Certificate(); X509Certificate x509Certificate = (X509Certificate) buildCertificate.buildCert(x509Cert); System.out.println(x509Certificate); PrivateKey privateKey = buildCertificate.buildKey(pk); SSLKeyManager keyManager = new SSLKeyManager(privateKey, new X509Certificate[]{x509Certificate}); sslc.init(new KeyManager[]{keyManager}, null, null); SSLServerSocketFactory sslServer = sslc.getServerSocketFactory(); SSLServerSocket sslServerSocket = (SSLServerSocket) sslServer.createServerSocket(8030); Boolean flag = true; System.out.println("wait for customer connect"); while (flag) { Socket s = sslServerSocket.accept(); System.out.println("connected"); ObjectOutputStream os = new ObjectOutputStream(s.getOutputStream()); os.writeObject("server: hello"); os.flush(); ObjectInputStream input = new ObjectInputStream(s.getInputStream()); System.out.println(input.readObject()); os.close(); System.out.println(); s.close(); } sslServerSocket.close(); } catch (ClassNotFoundException ex) { Logger.getLogger(SSLServer.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(SSLServer.class.getName()).log(Level.SEVERE, null, ex); } catch (KeyManagementException ex) { Logger.getLogger(SSLServer.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(SSLServer.class.getName()).log(Level.SEVERE, null, ex); } } public static void main(String args[]) { SSLServer sslServer = new SSLServer(); sslServer.sslServerSocket(); } }
建立SSLServerSocket
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.ssl; import com.security.SSLClientSocket; import com.security.SSLTrustManager; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; public class SSLClient { public void clientSocket() { try { SSLContext context = getContext(); SSLSocketFactory ssf = context.getSocketFactory(); SSLSocket ss = (SSLSocket) ssf.createSocket("127.0.0.1", 8030); Certificate[] aCerts = ss.getSession().getPeerCertificates(); System.out.println(aCerts[0]); ObjectInputStream os = new ObjectInputStream(ss.getInputStream()); System.out.println(os.readObject()); ObjectOutputStream out = new ObjectOutputStream(ss.getOutputStream()); out.writeObject("client: hello"); os.close(); out.close(); ss.close(); } catch (ClassNotFoundException ex) { Logger.getLogger(SSLClient.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(SSLClient.class.getName()).log(Level.SEVERE, null, ex); } } public SSLContext getContext() { try { BuildCertificate buildCertificate = new BuildCertificate(); String x509Cert = buildCertificate.getX509Certificate(); X509Certificate x509Certificate = (X509Certificate) buildCertificate.buildCert(x509Cert); SSLContext context = SSLContext.getInstance("SSL"); context.init(null, new TrustManager[]{new SSLTrustManager(new X509Certificate[]{x509Certificate})}, null); return context; } catch (KeyManagementException ex) { Logger.getLogger(SSLClient.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(SSLClient.class.getName()).log(Level.SEVERE, null, ex); } return null; } public static void main(String args[]) { SSLClient sslClient = new SSLClient(); sslClient.clientSocket(); } }
建立SSLClientSocket
package com.security; import java.net.Socket; import java.security.Principal; import java.security.PrivateKey; import java.security.cert.X509Certificate; import javax.net.ssl.X509KeyManager; public class SSLKeyManager implements { private PrivateKey pk ; private X509Certificate[] x509; public SSLKeyManager(PrivateKey pk,X509Certificate[] x509){ this.pk = pk; this.x509 = x509; } public String[] getClientAliases(String string, Principal[] prncpls) { return new String[]{"default"}; } public String chooseClientAlias(String[] strings, Principal[] prncpls, Socket socket) { return "default"; } public String[] getServerAliases(String string, Principal[] prncpls) { return new String[]{"default"}; } public String chooseServerAlias(String string, Principal[] prncpls, Socket socket) { return "default"; } public X509Certificate[] getCertificateChain(String string) { return this.x509; } public PrivateKey getPrivateKey(String string) { return this.pk; } }
自定义X509KeyManager
package com.security; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class SSLTrustManager implements X509TrustManager{ private X509Certificate[] x509; public SSLTrustManager(X509Certificate[] x509){ this.x509 = x509; } public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { if (x509 == null) { return; } for (int i = 0; i < x509.length; i++) { if (xcs[0].equals(x509[i])) { System.out.println("verity pass"); return; } } throw new CertificateException("not match the certificate,verity failed"); } public X509Certificate[] getAcceptedIssuers() { return null; } }
自定义X509TrustManager,这里checkServerTrusted验证服务端证书。
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.ssl; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.HttpsURLConnection; public class HttpsConn { public void connenct() { try { URL url = new URL("https://www.liu.com"); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); https.setDoInput(true); https.setDoOutput(true); https.setRequestMethod("POST"); SSLClient client = new SSLClient(); https.setSSLSocketFactory(client.getContext().getSocketFactory()); //可以验证服务器证书 https.setRequestProperty("name", "liu"); https.setRequestProperty("password", "123"); BuildCertificate buildCertificate = new BuildCertificate(); String x509Cert = buildCertificate.getX509Certificate(); String data = "cert=" + x509Cert + "&computerName=abc"; OutputStream os = https.getOutputStream(); os.write(data.getBytes()); os.flush(); os.close(); } catch (IOException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } } public void connect2() { try { URL url = new URL("https://www.liu.com"); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); https.setDoInput(true); https.setDoOutput(true); https.setRequestMethod("POST"); SSLClient client = new SSLClient(); https.setSSLSocketFactory(client.getContext().getSocketFactory()); //可以验证服务器证书 Signature sign = Signature.getInstance("MD5withRSA"); BuildCertificate buildCertificate = new BuildCertificate(); String pk = buildCertificate.getPrivateKey(); PrivateKey privateKey = buildCertificate.buildKey(pk); sign.initSign(privateKey); sign.update("abc".getBytes()); String computerName = Base64.encodeBase64String(sign.sign()); https.setRequestProperty("computerName", computerName); https.setRequestProperty("name", "liu"); https.setRequestProperty("password", "123"); } catch (InvalidKeyException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } catch (SignatureException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } } public static void main(String args[]) { HttpsConn httpsConn = new HttpsConn(); httpsConn.connenct(); } }
这里既验证了服务端,也验证了客户端,前提是客户端的证书已经传输过去。
相关推荐
下面将根据提供的压缩包文件名“实战 Linux Socket编程代码”来解析其中可能包含的知识点。 1. **Socket基础知识**:Socket是网络通信的基础,它是进程间通信的一种方式,特别适用于跨网络的通信。在Linux系统中,...
这两个文件可能包含 SSL 认证和测试相关的代码或者脚本,用于验证 SSL/TLS 连接的安全性和正确性。 7. **Openssl_ex** 这可能是 OpenSSL 的扩展实例或者练习项目,包含了一些高级用法,例如自定义加密算法、实现...
这个"asp.net代码练习 work021"很可能是一个学习资源或者项目实践,旨在帮助用户提升在ASP.NET平台上的编程技能。 在ASP.NET中,开发者可以使用多种语言,如C#或VB.NET,来编写服务器端代码。工作流程通常包括以下...
在"work020"这个压缩包中,我们可以推测它包含了与ASP.NET相关的代码练习或项目。 在ASP.NET中,主要的知识点包括: 1. **页面生命周期**:ASP.NET页面从请求到响应的过程中,经历了一系列的生命周期阶段,如初始...
【韩顺平视频全部代码】是一份集合了韩顺平老师教学视频中的示例代码,主要涉及了JSP(JavaServer Pages)技术和JavaMail的相关应用。...这个压缩包是一个很好的实战练习和学习资源,值得仔细研究。
在本项目"learn-node-fundamentals: https的练习代码"中,我们主要关注的是通过Node.js学习基础概念,特别是与HTTPS(超文本传输安全协议)相关的部分。Node.js是一个使用JavaScript进行服务器端编程的开放源代码、...
6. **安全性**:ASP.NET提供了多种安全特性,如身份验证、授权、SSL加密等。工作038可能会实现用户登录、角色管理,确保只有授权用户能访问特定资源。 7. **部署与性能优化**:项目开发完成后,需要部署到服务器上...
10. **安全性**:J2EE提供了多种安全机制,包括角色基的安全性、SSL/TLS加密、容器管理的身份验证和授权,以及对EJB方法的访问控制。 通过这些练习,开发者将有机会深入理解J2EE的各个组件,学习如何在实际项目中...
本项目“grunt-custom-task:https的练习代码”显然关注的是如何创建自定义的Grunt任务,特别是与HTTPS相关的实践。 Grunt的工作方式是通过安装各种插件来执行特定的任务,而自定义任务则允许开发者根据项目需求定制...
然后,在Rails的`config/puma.rb`配置文件中,添加以下代码来启用SSL支持: ```ruby bind 'tcp://0.0.0.0:3000', ssl: true, cert: '/path/to/cert.pem', key: '/path/to/key.pem' ``` 确保替换`/path/to/cert.pem...
4. **文档格式**:使用.doc文件格式,这表明文档可能是Microsoft Word创建的传统文本或报告,可能包含代码示例、流程图、伪代码等,便于理解和实现ATM系统。 5. **银行交易处理**:在实际的ATM系统中,涉及银行交易...
10. **实战项目**:“学员练习参考答案”可能包含一系列练习题目和示例代码,学员可以通过动手实践来巩固所学知识,同时提供参考答案供对比和学习。 总的来说,【北大青鸟6.0,S2 网上银行代码】这套教程为学员提供...
5. **安全机制**:包括用户认证(如OAuth、JWT)、支付安全(如SSL加密、第三方支付平台集成)和防止SQL注入、XSS攻击的安全措施。 6. **部署配置**:涉及服务器环境搭建、负载均衡、日志管理和持续集成/持续部署(C...
在C#编程语言中,网络应用...提供的压缩包文件“C#网络应用编程基础练习题与答案”应该包含了一些练习题和解答,可以帮助你巩固这些概念,并通过实际操作加深理解。记得动手实践,理论结合实际,是学习网络编程的关键。
在提供的“WCF练习及文档”压缩包中,很可能包含了创建简单WCF服务和客户端的步骤、示例代码以及相关解释,这些资料将帮助你更好地理解和应用WCF技术。 总结,WCF是一个强大的服务框架,它集成了多种通信机制,并...
这份源代码提供了丰富的示例和练习,帮助初学者深入理解网络编程的基本原理。以下是对这份资源中涉及的知识点的详细解释: 1. **Python网络编程基础**:Python网络编程涉及创建客户端和服务端应用,处理TCP/IP、UDP...
5. **HTTPS协议**:HTTP的安全版本,基于SSL/TLS协议,用于加密传输数据,确保数据隐私和安全。 6. **TCP连接与套接字编程**:TCP连接包括三次握手建立连接和四次挥手断开连接。套接字编程涉及创建、绑定、监听、...
7. **源代码分析**:提供的源代码可能是书中的实例或练习,读者可以通过阅读和运行这些代码,加深对网络编程概念的理解,并学习实际的编程技巧。 8. **性能优化**:如何利用C++的特性,如模板、RAII(资源获取即...
最后,"worker7t6_gulfuhs"可能是这次练习的作者或者特定的代码库名称,而"homework"这个压缩包文件可能包含了整个练习项目的源代码,供学习者参考和实践。 总的来说,这个练习涵盖了从静态网页到动态交互的完整...
在C#编程语言中,源程序是程序员使用C#语法编写的应用程序代码,这些代码以文本文件的形式存在,通常扩展名为.cs。C#源程序练习是开发者提升技能、理解和掌握C#特性的关键途径。本练习主要关注的是P2P(Peer-to-Peer...