- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
数字化时代,网络编程已成为软件开发中不可或缺的一环,尤其对于 .NET 开发者而言,掌握 C# 中的网络编程技巧是迈向更高层次的必经之路。无论是构建高性能的 Web 应用,还是实现复杂的分布式系统,网络编程都是支撑这一切的基石.
本篇主要为 .NET 开发者提供一份全面而精炼的 C# 网络编程入门,从基础知识到高级话题,逐一剖析,帮助你建立起扎实的网络编程功底,让你在网络世界的编码之旅中游刃有余.
HTTP(Hypertext Transfer Protocol)是互联网上应用最为广泛的一种网络协议,主要用于从万维网服务器传输超文本到本地浏览器的传输协议.
在C#中,处理HTTP请求有多种方式,从传统的System.Net命名空间到现代的HttpClient类,每种方法都有其适用场景.
HttpClient
发送HTTP请求HttpClient是C#中推荐用于发送HTTP请求的类,它提供了异步的API,可以更好地处理长时间运行的操作,避免阻塞UI线程.
以下是一个简单的GET请求示例:
using System; using System.Net.Http; using System.Threading.Tasks; public class HttpClientExample { public static async Task Main() { using var client = new HttpClient(); var response = await client.GetAsync("https://api.example.com/data"); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); } else { Console.WriteLine($"Failed to retrieve data: {response.StatusCode}"); } } }
WebClient
发送HTTP请求尽管WebClient类仍然存在于.NET Framework中,但在.NET Core和后续版本中,它已被标记为过时,推荐使用HttpClient.
不过,对于简单的同步请求,WebClient仍然可以使用:
using System; using System.IO; using System.Net; class WebClientExample { public static void Main() { using (var client = new WebClient()) { try { string result = client.DownloadString("https://api.example.com/info"); Console.WriteLine(result); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } } }
HttpRequestMessage
和 HttpMessageHandler
对于更复杂的HTTP请求,如需要自定义请求头或处理认证,可以使用HttpRequestMessage和HttpMessageHandler.
这种方式提供了更多的灵活性和控制:
using System; using System.Net.Http; using System.Threading.Tasks; class HttpRequestMessageExample { public static async Task Main() { using var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/info"); request.Headers.Add("Authorization", "Bearer your-access-token"); var response = await client.SendAsync(request); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); } else { Console.WriteLine($"Failed to retrieve data: {response.StatusCode}"); } } }
HttpClient
时,确保在一个应用程序的生命周期内重用同一个实例,而不是每次请求都创建新的实例。HttpClient
时,可以通过CancellationToken
来控制请求的超时和取消。通过掌握这些知识点,能够在C#中有效地处理各种HTTP请求,从简单的GET请求到复杂的POST请求,包括身份验证和错误处理.
WebSocket是一种在单个TCP连接上进行全双工通信的协议,它提供了比传统HTTP请求/响应模型更低的延迟和更高的效率,非常适合实时数据流、聊天应用、在线游戏等场景。在C#中,无论是服务器端还是客户端,都可以使用WebSocket进行通信.
在C#中,你可以使用System.Net.WebSockets命名空间下的ClientWebSocket类来创建WebSocket客户端。下面是一个简单的示例,展示了如何连接到WebSocket服务器并发送和接收消息:
using System; using System.IO.Pipelines; using System.Net.WebSockets; using System.Text; using System.Threading; using System.Threading.Tasks; /// <summary> /// WebSocket客户端类,用于与WebSocket服务器建立连接和通信。 /// </summary> public class WebSocketClient { /// <summary> /// 客户端WebSocket实例。 /// </summary> private readonly ClientWebSocket _webSocket = new ClientWebSocket(); /// <summary> /// 用于取消操作的CancellationTokenSource。 /// </summary> private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); /// <summary> /// 连接到指定的WebSocket服务器。 /// </summary> /// <param name="uri">WebSocket服务器的URI。</param> public async Task Connect(string uri) { // 使用提供的URI连接到WebSocket服务器 await _webSocket.ConnectAsync(new Uri(uri), _cancellationTokenSource.Token); } /// <summary> /// 向WebSocket服务器发送消息。 /// </summary> /// <param name="message">要发送的消息字符串。</param> public async Task SendMessage(string message) { // 将消息转换为UTF8编码的字节 byte[] buffer = Encoding.UTF8.GetBytes(message); // 创建ArraySegment,封装要发送的字节缓冲区 ArraySegment<byte> segment = new ArraySegment<byte>(buffer); // 发送消息到WebSocket服务器 await _webSocket.SendAsync(segment, WebSocketMessageType.Text, true, _cancellationTokenSource.Token); } /// <summary> /// 接收WebSocket服务器发送的消息。 /// </summary> /// <param name="onMessageReceived">接收到消息时调用的回调函数。</param> public async Task ReceiveMessage(Action<string> onMessageReceived) { // 当WebSocket连接处于打开状态时,持续接收消息 while (_webSocket.State == WebSocketState.Open) { var buffer = new byte[1024]; // 接收来自WebSocket服务器的数据 var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), _cancellationTokenSource.Token); // 如果接收到的类型为关闭,则关闭连接 if (result.MessageType == WebSocketMessageType.Close) { await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); break; } // 将接收到的字节转换为字符串,并通过回调函数处理 var receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count); onMessageReceived(receivedMessage); } } /// <summary> /// 断开与WebSocket服务器的连接。 /// </summary> public async Task Disconnect() { // 取消接收和发送操作 _cancellationTokenSource.Cancel(); // 关闭WebSocket连接 await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); } }
在服务器端,可以使用ASP.NET Core中的Microsoft.AspNetCore.WebSockets来支持WebSocket.
下面是一个简单的WebSocket服务端点配置示例:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using System; using System.Threading.Tasks; public class Startup { /// <summary> /// 配置服务容器。 /// </summary> /// <param name="services">服务集合。</param> public void ConfigureServices(IServiceCollection services) { // 添加控制器服务 services.AddControllers(); } /// <summary> /// 配置应用管道。 /// </summary> /// <param name="app">应用构建器。</param> /// <param name="env">主机环境。</param> public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 在开发环境中启用异常页面 if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 启用路由 app.UseRouting(); // 启用WebSocket中间件 app.UseWebSockets(); // 配置端点处理器 app.UseEndpoints(endpoints => { // 映射默认的GET请求处理器 endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); // 映射WebSocket请求处理器 endpoints.Map("/ws", async context => { // 检查当前请求是否为WebSocket请求 if (context.WebSockets.IsWebSocketRequest) { // 接受WebSocket连接 using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); // 持续监听WebSocket消息 while (true) { // 准备接收缓冲区 var buffer = new byte[1024 * 4]; // 接收WebSocket消息 var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); // 如果收到的类型为关闭消息,则关闭连接 if (result.MessageType == WebSocketMessageType.Close) { await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); break; } // 解码接收到的消息 var message = Encoding.UTF8.GetString(buffer, 0, result.Count); Console.WriteLine($"Received: {message}"); // 回复消息给客户端 await webSocket.SendAsync( new ArraySegment<byte>(Encoding.UTF8.GetBytes($"Echo: {message}")), result.MessageType, result.EndOfMessage, CancellationToken.None); } } else { // 如果不是WebSocket请求,则返回400错误 context.Response.StatusCode = 400; } }); }); } }
在上面的服务器端代码中,首先启用了WebSocket中间件,然后映射了一个/ws端点来处理WebSocket连接.
当收到连接请求时,我们接受连接并进入循环,监听客户端发送的消息,然后简单地回传一个回显消息.
WebSocket为C#开发者提供了强大的实时通信能力,无论是构建复杂的实时数据流应用还是简单的聊天室,WebSocket都是一个值得考虑的选择。通过掌握客户端和服务器端的实现细节,可以充分利用WebSocket的优势,创建高性能和低延迟的实时应用.
Socket编程是计算机网络通信中的基础概念,它提供了在不同计算机之间发送和接收数据的能力.
在C#中,Socket编程主要通过System.Net.Sockets命名空间下的Socket类来实现。Socket可以用于创建TCP/IP和UDP两种主要类型的网络连接,分别对应于流式套接字(Stream Sockets)和数据报套接字(Datagram Sockets).
Socket地址族:指定网络协议的类型,如AddressFamily.InterNetwork用于IPv4.
Socket类型:SocketType.Stream用于TCP,SocketType.Dgram用于UDP.
Socket协议:ProtocolType.Tcp或ProtocolType.Udp,分别用于TCP和UDP.
TCP Socket客户端通常用于建立持久的连接,并通过流的方式发送和接收数据.
以下是一个简单的TCP客户端示例:
using System; using System.Net; using System.Net.Sockets; using System.Text; public class TcpClientExample { public static void Main() { try { // 创建一个新的Socket实例 using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { // 连接到服务器 IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000); socket.Connect(remoteEP); // 发送数据 string message = "Hello Server!"; byte[] data = Encoding.ASCII.GetBytes(message); socket.Send(data); // 接收服务器响应 data = new byte[1024]; int bytes = socket.Receive(data); Console.WriteLine("Received: {0}", Encoding.ASCII.GetString(data, 0, bytes)); } } catch (Exception e) { Console.WriteLine("Error: {0}", e.ToString()); } } }
TCP Socket服务器负责监听客户端的连接请求,并处理来自客户端的数据.
以下是一个简单的TCP服务器示例:
using System; using System.Net; using System.Net.Sockets; using System.Text; public class TcpServerExample { public static void Main() { try { // 创建一个新的Socket实例 using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { // 绑定到本地端口 IPAddress ipAddress = IPAddress.Any; IPEndPoint localEP = new IPEndPoint(ipAddress, 11000); listener.Bind(localEP); // 监听连接 listener.Listen(10); // 接受客户端连接 Console.WriteLine("Waiting for a connection..."); Socket handler = listener.Accept(); // 接收数据 byte[] data = new byte[1024]; int bytes = handler.Receive(data); Console.WriteLine("Text received: {0}", Encoding.ASCII.GetString(data, 0, bytes)); // 发送响应 string response = "Hello Client!"; byte[] responseData = Encoding.ASCII.GetBytes(response); handler.Send(responseData); } } catch (Exception e) { Console.WriteLine("Error: {0}", e.ToString()); } } }
UDP Socket用于无连接的、不可靠的网络通信,通常用于实时数据传输,如视频流或游戏.
以下是一个简单的UDP客户端和服务器示例:
UDP客户端 。
using System; using System.Net; using System.Net.Sockets; using System.Text; public class UdpClientExample { public static void Main() { try { // 创建一个新的Socket实例 using (UdpClient client = new UdpClient()) { // 发送数据 string message = "Hello UDP Server!"; byte[] data = Encoding.ASCII.GetBytes(message); IPEndPoint server = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); client.Send(data, data.Length, server); // 接收服务器响应 data = client.Receive(ref server); Console.WriteLine("Received: {0}", Encoding.ASCII.GetString(data)); } } catch (Exception e) { Console.WriteLine("Error: {0}", e.ToString()); } } }
UDP服务器 。
using System; using System.Net; using System.Net.Sockets; using System.Text; public class UdpServerExample { public static void Main() { try { // 创建一个新的Socket实例 using (UdpClient listener = new UdpClient(11000)) { // 接收数据 IPEndPoint client = new IPEndPoint(IPAddress.Any, 0); byte[] data = listener.Receive(ref client); Console.WriteLine("Text received: {0}", Encoding.ASCII.GetString(data)); // 发送响应 string response = "Hello UDP Client!"; byte[] responseData = Encoding.ASCII.GetBytes(response); listener.Send(responseData, responseData.Length, client); } } catch (Exception e) { Console.WriteLine("Error: {0}", e.ToString()); } } }
以上示例展示了如何使用C#中的Socket类来实现TCP和UDP的客户端与服务器通信.
在实际应用中,可能还需要处理并发连接、错误处理和资源管理等问题.
此外,对于TCP通信,考虑到性能和资源使用,通常建议使用异步编程模型.
C# 中进行网络编程时,网络安全是一个至关重要的方面,涉及数据传输的保密性、完整性和可用性。以下是一些关键的网络安全知识点,它们对于构建安全的网络应用程序至关重要:
在C#中使用HttpClient时,可以通过HttpClientHandler类来配置SSL/TLS相关的选项,确保HTTPS请求的安全性.
下面是一个示例,演示了如何使用HttpClientHandler来配置SSL/TLS设置:
using System; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; class Program { static async Task Main() { // 创建 HttpClientHandler 实例 var handler = new HttpClientHandler(); // 配置 SSL/TLS 设置 // 设置检查服务器证书的委托 handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; // 设置是否自动重定向 handler.AllowAutoRedirect = true; // 设置代理 // handler.UseProxy = true; // handler.Proxy = new WebProxy("http://proxy.example.com:8080"); // 创建 HttpClient 实例 using var httpClient = new HttpClient(handler); // 设置请求头部 httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // 发送 HTTPS 请求 var response = await httpClient.GetAsync("https://api.example.com/data"); // 检查响应状态 if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); } else { Console.WriteLine($"Failed to retrieve data: {response.StatusCode}"); } } }
解释 。
ServerCertificateCustomValidationCallback
:此属性允许你指定一个委托,用来验证服务器的SSL证书。在这个示例中,我们使用了HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
,它会接受任何证书,这在测试环境中可能有用,但强烈建议在生产环境中使用更严格的证书验证逻辑。AllowAutoRedirect
:此属性控制是否允许HttpClient
自动处理重定向。默认情况下,它是开启的。UseProxy
和 Proxy
:如果需要通过代理服务器发送请求,可以配置这两个属性。DefaultRequestHeaders
:用于设置请求的默认头部,如Accept
,以指定期望的响应格式。注意事项:
DangerousAcceptAnyServerCertificateValidator
,因为它绕过了正常的证书验证,可能使应用程序暴露于中间人攻击。在生产环境中,应该实现自己的证书验证逻辑,确保只接受有效和可信的证书。SslProtocols
属性进一步定制HttpClientHandler
的SSL/TLS设置。SslProtocols.Tls12
或SslProtocols.Tls13
,以限制使用的协议版本。在C#中安全地存储密码是一个至关重要的实践,尤其是当涉及到用户账户和敏感信息时。为了保护密码不被泄露或破解,应避免以明文形式存储密码,而是采用加密或哈希的方式.
以下是一些推荐的实践:
使用安全的哈希函数,如SHA-256或SHA-512,可以将密码转换为一个固定长度的摘要。但是,简单的哈希容易受到彩虹表攻击,因此需要加入盐值(salt).
示例代码:
using System; using System.Security.Cryptography; using System.Text; public static class PasswordHasher { public static string HashPassword(string password, byte[] salt) { using (var sha256 = SHA256.Create()) { var passwordSalted = Encoding.UTF8.GetBytes(password + Encoding.UTF8.GetString(salt)); var hash = sha256.ComputeHash(passwordSalted); return Convert.ToBase64String(hash); } } public static byte[] GenerateSalt() { using (var rng = new RNGCryptoServiceProvider()) { var salt = new byte[32]; rng.GetBytes(salt); return salt; } } } // 使用示例 byte[] salt = PasswordHasher.GenerateSalt(); string hashedPassword = PasswordHasher.HashPassword("password123", salt);
在哈希密码之前,先将随机生成的盐值与密码结合。这可以防止彩虹表攻击和暴力破解.
使用像PBKDF2、bcrypt、scrypt或Argon2这样的慢速哈希函数,可以显著增加破解难度,因为它们设计时考虑了防止暴力破解.
示例代码:
using System; using System.Linq; using System.Security.Cryptography; using System.Text; public static class PasswordHasher { public static string HashPasswordUsingBcrypt(string password) { using (var bcrypt = new Rfc2898DeriveBytes(password, 16, 10000)) // 16 bytes of salt, 10000 iterations { return Convert.ToBase64String(bcrypt.GetBytes(24)); // 24 bytes of hash } } } // 使用示例 string hashedPassword = PasswordHasher.HashPasswordUsingBcrypt("password123");
在数据库中,除了存储哈希后的密码,还应存储用于该密码的盐值,以便在验证时使用相同的盐值重新计算哈希.
在用户登录时,从数据库中检索哈希和盐值,使用相同的哈希函数和盐值对输入的密码进行哈希,然后与存储的哈希值进行比较.
示例代码:
public static bool VerifyPassword(string inputPassword, string storedHash, byte[] storedSalt) { string hashOfInput = PasswordHasher.HashPassword(inputPassword, storedSalt); return hashOfInput == storedHash; }
密码重置问题的答案应该像密码一样被安全地处理,避免以明文形式存储.
ASP.NET Core提供了内置的密码哈希和验证方法,使用这些框架通常比手动实现更安全。总之,安全地存储密码涉及到使用强哈希算法、加盐、适当的迭代次数和存储机制。同时,保持对最新安全实践的关注,并定期更新代码以应对新的威胁.
使用参数化查询或ORM工具等,防止SQL注入攻击.
string query = "SELECT * FROM SystemUser WHERE Username = @username"; SqlCommand command = new SqlCommand(query, connection); command.Parameters.AddWithValue("@username", inputUsername);
对用户输入进行合适的编码和验证,防止恶意脚本注入.
string userContent = "<script>alert('XSS');</script>"; string encodedContent = HttpUtility.HtmlEncode(userContent);
ASP.NET MVC可以使用Anti-Forgery Token等机制来防止CSRF攻击.
@Html.AntiForgeryToken()
使用更高级的身份验证机制,如JWT(JSON Web Token),并在应用中实施合适的授权策略.
[Authorize] public ActionResult SecureAction() { // 安全操作 }
在C#中,判断一个文件是否"安全"可以从多个角度考量,这通常涉及到文件的来源、内容、权限以及是否包含潜在的恶意代码等.
下面我会介绍几种可能的方法来检查文件的安全性:
确保文件是从可信的源下载或获取的。在Web应用程序中,可以使用Content-Disposition响应头来检查文件是否作为附件提供,以及文件名是否符合预期.
通过检查文件的扩展名或MIME类型来确定文件类型是否符合预期,例如,如果期望图片文件,那么只接受.jpg, .png等扩展名.
private bool IsFileSafeByExtension(string filePath) { string[] allowedExtensions = { ".jpg", ".png", ".gif" }; string extension = Path.GetExtension(filePath).ToLower(); return allowedExtensions.Contains(extension); }
使用文件签名或魔法数字来验证文件的实际类型与声明的类型是否一致,防止扩展名欺骗.
private bool IsFileSafeByContent(string filePath) { byte[] magicNumbers = File.ReadAllBytes(filePath); if (magicNumbers.Length >= 2 && magicNumbers[0] == 0xFF && magicNumbers[1] == 0xD8) // JPEG { return true; } // Add checks for other formats... return false; }
使用反病毒软件或在线API来检查文件是否含有病毒或恶意软件.
private bool IsFileSafeFromVirus(string filePath) { // Example: Using an antivirus API to scan the file. // This is just a placeholder and you should replace it with actual antivirus software integration. return AntivirusApi.Scan(filePath); }
确保文件具有正确的权限,以防止未经授权的访问.
private bool IsFileSafeByPermissions(string filePath) { var fileInfo = new FileInfo(filePath); var security = fileInfo.GetAccessControl(); // Check permissions here... return true; // Placeholder logic }
限制文件的大小,避免消耗过多的磁盘空间或内存.
private bool IsFileSafeBySize(string filePath, long maxSizeInBytes) { var fileInfo = new FileInfo(filePath); return fileInfo.Length <= maxSizeInBytes; }
在Web应用中,使用CSP来限制加载的资源类型和来源,防止XSS等攻击.
private bool IsFileSafe(string filePath) { return IsFileSafeByExtension(filePath) && IsFileSafeByContent(filePath) && IsFileSafeFromVirus(filePath) && IsFileSafeByPermissions(filePath) && IsFileSafeBySize(filePath, 1024 * 1024); // Limit to 1MB }
请注意,上述代码片段仅作为示例,实际应用中可能需要调整和补充具体的实现细节,例如引入实际的病毒扫描库或API,以及更复杂的权限和内容检查逻辑.
安全检查是多层面的,需要结合具体的应用场景和需求进行综合考量.
Cookies是Web开发中用于存储用户信息的一种常用机制,它们可以在客户端浏览器中保存小量的数据,以便服务器可以跟踪用户的偏好设置、登录状态等信息。然而,如果Cookie处理不当,可能会引发严重的安全问题,如数据泄露、会话劫持(Session Hijacking)和跨站脚本攻击(XSS)。因此,确保Cookie的安全处理至关重要.
以下是处理Cookie时应当遵循的一些最佳实践:
通过遵循这些最佳实践,可以大大增强应用程序的安全性,保护用户数据免受恶意攻击。在Web开发中,安全的Cookie处理不仅是技术要求,也是对用户隐私和数据安全的责任体现.
using System; using System.Web; public class CookieHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { // 创建一个新的Cookie对象 HttpCookie cookie = new HttpCookie("UserSession"); // 设置Cookie值 cookie.Value = "123456"; // 假设这是用户的唯一标识符 // 设置Cookie的过期时间 cookie.Expires = DateTime.Now.AddDays(1); // 设置Cookie在一天后过期 // 设置HttpOnly属性以增加安全性 cookie.HttpOnly = true; // 如果你的网站支持HTTPS,设置Secure属性 if (context.Request.IsSecureConnection) cookie.Secure = true; // 添加Cookie到响应中 context.Response.AppendCookie(cookie); } public bool IsReusable { get { return false; } } }
在.NET Core或.NET 6+中,使用不同的API来处理Cookie,例如Microsoft.AspNetCore.Http命名空间下的IResponseCookies接口.
通过文章的全面介绍 C# 网络编程,相信对这一块内容有了了解和理解。从简单的 HTTP 请求到复杂的套接字通信,从异步编程模型到安全协议的应用,每一步都为我们构建现代网络应用奠定了坚实的基。在实际项目中,根据需求深入学习和实践这些知识点,将有助于提升.NET开发者在网络编程领域的能力。持续学习和实践是成为优秀 .NET 开发者的不二法门.
如果觉得这篇文章对你有用,欢迎加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行交流心得,共同成长.
最后此篇关于C#网络编程:.NET开发者的核心技能的文章就讲到这里了,如果你想了解更多关于C#网络编程:.NET开发者的核心技能的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
所以我刚刚开始编写 iPhone 应用程序,一个潜在的雇主问我,“你的开发者句柄是什么?”他所说的“开发者句柄”到底是什么意思? 最佳答案 很可能您的应用程序在 iTunes 商店中列出的名称。这可以
我刚刚编译并运行了 hello world 应用程序,它运行良好。我通读了 android 文档中的一堆内容,内容涉及 android 的差异组件以及它们如何协同工作。现在我想制作一些链接到各种操作的
我不是 Android 开发人员,我试图了解他们在图形资源方面需要什么来制作可在许多 Android 设备上运行的应用程序。 我已经(尝试)阅读此页 http://developer.android.
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
如何编写程序来实现滑动 MUITableCell 的功能。我已经有一个我一直在使用的 MUITableCell 的子类。我是否只处理其中的滑动,就像处理 View 一样? 最佳答案 您需要实现此方法:
堆栈溢出, 是否有其他人在 Facebook 上遇到阻止注册为 Facebook 开发人员的能力的错误?该按钮对我显示为灰色。 当我尝试单击按钮将“否”切换为"is"时,没有任何功能。 我在互联网和
我正在尝试为 iOS Developer PageControl Sample 实现建议的优化。 .这是我在 PhoneContentController 中使用的代码: // A possible
您好,我写了一段代码来使用 Pubnub channel 发布 json: pubnubMessage = new Pubnub("demo", "demo"); Suppor
我正在熟悉 iOS 上的 SQLite。我正在尝试进行简单的用户注册,但是年龄值 (NSInteger) 总是变成一些大的负数,例如 -1073752692。这是我的注册码: - (User*
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 6 年前。 Improv
我的问题是,当我检查位置服务和数据是否关闭时,我的手机不会弹出没有启用数据或位置访问的通知,就像如果其中一个为假,它会显示通知。此功能在我的华为 P8 Lite 上不起作用,但在我的 Nexus 模拟
我正在开发一个需要集成 Paypal API 的 php 项目。我选择了 REST API。但我有一个企业账户(沙盒)。是否可以使用此帐户类型调用 REST API? 最佳答案 您需要使用任何有效的
我 6 个月前在 http://developer.paypal.com 上创建了一个应用程序.我已经创建了一些帐户以在沙盒模式下进行测试。昨天我检查了http://developer.paypal.
我很难理解 UIViewController 中的几个方法,但首先我会说出我认为它们的用途(忽略界面生成器,因为我没有使用它): -init:初始化在低内存情况下不需要释放的非 View 相关的东西(
我在构建我的应用程序时达到了 youtube api 配额限制,所以我向请求添加了一个开发人员 key ,现在我收到 403 错误:无效的开发人员 key 。 我曾多次尝试重新创建我的项目和 api
我搜索了http://espn.go.com/apis/devcenter/但找不到任何可以创建 API key 的地方。我还在 ESPN 创建了一个帐户,但没有运气。 最佳答案 4 个月前未公开 (
我阅读了处理此类问题的不同主题,但我仍然没有答案。这是我的问题: 在我的头文件中,我有这个: int cl, ch, _a = a, _b = b;\ __asm__ ("smull %0,
我实际上正在使用fbconnect,并且我正在尝试获取代表一个月前的unix时间。我对 1970 年以来的事情感到非常困惑。因为有人给我指出了正确的方向? 最佳答案 与 Unix epoch ,时间“
是否有任何工具可以让我监控内存使用和泄漏?例如,我想跟踪手动释放对象与启用 ARC 时自动释放对象时的内存使用情况。 最佳答案 它被称为 Instruments,您可以从 Product -> Pro
我正在使用 AllRoundAutomatation 的 Pl/sql 开发人员,现在我遇到了一个非常有趣的问题,我只想为 scoll up 配置 CTRL+UP 组合键!但我做不到,我该怎么做? 注
我是一名优秀的程序员,十分优秀!