前一段时间做过JAVA的Socket客户端转换为C#的Socket客户端的工作,最近开发的项目又需要用Java代码通过Socket的方式作为客户端去请求服务端交互数据的功能,这次对.NET和Java的一些常用技术点做个记录,由于没有涉及开发大并发量的socket服务器端,对分包、粘包和一些高性能的要求都没有分析过,本篇文章只以它们之间的常用使用方法以及Java的Socket转换为C#代码的方法作一定的记录。
一、Java Socket
在JDK1.4之前,java只能以同步的方式创建socket,异步只能用多线程方式的异步,java.net.ServerSocket 包可以创建服务端的socket处理器,客户端通过java.net.Socket 连接过来如:
private ServerSocket server = null;
private Socket socket = null;
InetAddress address = InetAddress.getByName("127.0.0.1");
server = new ServerSocket(3000,10000,address);
//监听窗口,等待连接
socket = server.accept();
这样服务端ServerSocket的accept()方法就会同步阻塞等待客户端连接,在收到客户端socket连接请求后,就会执行后续操作。服务端通过socket.getInputStream()来获取客户端输入的数据流,通过对socket.getOutputStream()读取流进行回写,返回给客户端信息。Socket客户端可以用:
Socket so = new Socket("127.0.0.1",3000);
InputStream is = so.getInputStream();
OutputStream os = so.getOutputStream();
的方式建立socket连接,比如这里可以直接对os进行发送数据到服务端:os.write(sendByte)。
JDK1.4后,增加了NIO的包可以创建非阻塞的异步Socket服务端和客户端,在java.nio包下java.nio.channels.ServerSocketChannel用于创建socket服务端,java.nio.channels.SocketChannel包用于创建socket接收端或客户端,它们通过java.nio.channels.Selector管理NIO的ServerSocketChannel通道,Selector通过事件的方式响应客户端的请求,为Selector注册事件的方式如:
// 通过open()方法找到Selector
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
// 注册接收请求事件到selector
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
事件还包括:SelectionKey.OP_READ读取事件,SelectionKey.OP_WRITE写操作事件,为serverSocketChannel注册事件后,就可以写一个循环,每当selector.select()接收到值时,就开始判断是什么事件,然后按照事件执行具体逻辑代码。建立异步Socket服务端代码如:
serverSocketChannel = ServerSocketChannel.open();
//配置为非阻塞
serverSocketChannel.configureBlocking(false);
//获取通道关联的服务器套接字
ServerSocket serverSocket = serverSocketChannel.socket();
//服务端绑定IP端口
serverSocket.bind(new InetSocketAddress("127.0.0.1", 3000));
这样通过serverSocketChannel建立了服务端监听,然后用上面的Selector为serverSocketChannel添加注册事件即可作为服务端监听各种客户端事件了。
Java中对TCP和UDP分别用不同的包来处理,UDP是用java.net.DatagramSocket包下的方法来处理。
二、.NET Socket
.NET下C#封装的Socket在System.Net.Sockets命名空间下,里面异步、同步的方法均用Socket类即可,并且TCP,UDP的选择直接根据 Socket的构造函数来确定,比如:Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ProtocolType可以选择TCP还是UDP,当为UDP时,需要用SocketType.Dgram类型的数据格式。.NET里有封装 TcpListener 和TcpClient来分别处理TCP请求的服务端和客户端,UdpClient 类来处理UDP请求的服务端和客户端,它们是基于Socket套接字的封装。使用上TcpListener、TcpClient和Java的风格很像,通过tcpClient.GetStream()返回数据流再操作数据,而UdpClient是通过直接send,receive的方式发送接收数据。.NET的Socket服务器端建立监听如:
IPEndPoint hostEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(hostEP);
socket.Listen(500);
Socket client = socket.Accept();
通过Accept方法同步等待获取一个连接的socket,当然也可以异步的方式等待客户端的连接请求,有新请求后,就可以用这个socket来处理数据。它可以用同步阻塞接收方法,如:
public int Receive(byte[] buffer);
public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags);
等用于同步接收客户端数据,也可以异步接收客户端数据的方式:
可以APM方式:public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state);
或者事件方式:public bool ReceiveAsync(SocketAsyncEventArgs e);
处理数据的方式比如:
byte[] bytesSendStr = new byte[1024];
int bytes = client.Receive(bytesSendStr);
string sendStr = Encoding.UTF8.GetString(bytesSendStr, 0, bytes);
sendStr = “服务端返回:” + sendStr;
bytesSendStr = Encoding.UTF8.GetBytes(sendStr);
client.Send(bytesSendStr, bytesSendStr.Length,SocketFlags.None);
服务端接收数据应该反复Receive客户端数据,直到接收数据返回的整数小于1,防止没有读取完数据,并且读取结果我觉得最好读取到byte里,因为一般socket都可能会用byte的前面字段作为标识,比如标识收取数据的长度,数据类型等。
作为Socket服务端,一般都要能同时处理大量的客户端socket请求,因此单线程来处理肯定不行,当每accept到一个客户端请求后,就开启一个线程来处理,存在大量线程开启的问题,并且客户端请求后发送数据和服务端返回数据等会导致服务端同步等待,造成线程消耗资源的浪费。因此一般服务端都会用异步的方式来处理客户端的请求。
三、Java Socket和C# Socket的不同
一般它们的区别有:创建socket的方式不一样;发送数据和接收数据方式不一样;还有就是Java中一般是用方法的方式设置配置参数,.NET是以属性的方式直接设置。
下面以TCP的方式说明几个,如Java创建客户端方式:
Socket socket = new Socket("127.0.0.1",3000);
.NET创建客户端方式:
Socket newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//服务器的IP和端口
IPEndPoint ie = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);
newclient.Connect(ie);
Java发送接收数据方式:
Socket socket = new Socket(“127.0.0.1”,3000);
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//发送数据
os.write(sendByte);
//读取服务端数据
returnStr = InputStreamTOString(is);
.NET发送接收数据方式:
byte[] msg = Encoding.UTF8.GetBytes(content);
//newclient.ReceiveTimeout = 10000;
//直接发送
int bytesSent = newclient.Send(msg);
//直接接收服务端
int bytesRec = newclient.Receive(data);
设置Socket参数的方法,比如Java设置参数:
//让socket及时发送,防止缓存数据不多时不发送
socket.setTcpNoDelay(true);
//接收数据超时时间
socket.setSoTimeout(30000);
.NET对应Java的上述设置为:
newclient.NoDelay = true;
newclient.ReceiveTimeout = 30000;
但如果为了把JAVA程序转换为C#程序,并且代码风格保持基本不变,可以用开源的一个项目:IKVM,它的主要一个类库:IKVM.OpenJDK.Core.dll,内部的命名空间基本和JAVA的包名保持一致,几乎一一对应,除了语法方面的写法不同,其他JAVA类库的写法都一样,因此写的代码几乎可以和JAVA一样。
上面粗略写了JAVA和.NET的一些Socket知识,如有不对,欢迎指正!
如转载,请注明来自:http://lawson.cnblogs.com/
相关推荐
在Java中,Socket类位于`java.net`包下,而在.NET中,Socket类位于`System.Net.Sockets`命名空间内。 2. **TCP连接**:Java和.NET的Socket通信通常基于TCP(传输控制协议),这是一种面向连接的、可靠的传输协议,...
在Java中,`java.net.Socket`类代表客户端Socket,用于建立与服务器的连接,并通过该连接发送和接收数据。而`java.net.ServerSocket`类则用于服务端,它监听特定端口的连接请求,一旦有客户端请求连接,就会创建一个...
在Android客户端和.NET服务器之间使用Socket通信,可以实现双向的数据流,这对于实时应用如即时通讯、在线游戏等至关重要。 **Android客户端的Socket实现** 1. **创建Socket连接**:在Android客户端,首先需要创建...
"java.net.SocketException Connection reset 解决方法" 在 Java 编程中,SocketException 是一种常见的异常,特别是在网络编程中。Conexion reset by peer 是一种特殊的 SocketException,它发生在客户端和服务器...
在Java端,Socket编程同样位于`java.net`包下,Java的Socket类负责处理客户端与服务器之间的连接。服务器端需要创建一个ServerSocket监听特定端口,等待客户端连接。当接收到连接请求时,ServerSocket的`accept`方法...
在Java中,`java.net.Socket` 和 `java.net.ServerSocket` 是两个主要的类,分别代表客户端和服务器端的Socket。客户端Socket用于连接到服务器,而服务器端Socket则监听特定端口,等待客户端的连接请求。 在屏幕...
- `java.net.Socket` 类是Android中的主要Socket实现,用于建立TCP连接。 - `ServerSocket` 类在服务器端使用,用于监听客户端的连接请求。 2. **.NET Socket通信基础** - .NET框架同样提供了Socket类,位于`...
- **.NET的ASP.NET**:ASP.NET是.NET平台下的Web开发框架,包括MVC、Web API和Blazor等多种开发模式。 8. **编程语言特性** - **Java的新特性**:如lambda表达式、Stream API、默认方法、模块化系统(Jigsaw)等...
在Java中,Socket类位于`java.net`包下,提供了多种构造函数和方法来实现网络连接的建立、数据交换以及连接的关闭。 1. **连接服务器** - 建立连接:客户端通常需要知道服务器的IP地址或域名以及服务端口。在Java...
Java和.NET是两种广泛使用的开发平台,它们各自拥有丰富的生态系统和强大的工具支持。这份"Java与.Net 经典练习题"旨在帮助开发者提升编程技能,尤其是对于算法的理解和运用。以下是一些相关的知识点: 1. **Java...
Java和.NET是两种广泛使用的软件开发平台,它们在企业级应用开发中占据着重要的地位。这份压缩包包含的“Java、.NET面试题(技术笔试题)各多套含答案word版”为求职者提供了宝贵的资源,帮助他们准备面试,提升就业...
1. **网络通信库**:JAVA中的`java.net`包提供了Socket和ServerSocket类,它们是建立客户端-服务器通信的基础。源代码中可能使用了这些类来创建连接并交换数据。 2. **多线程**:为了处理并发连接和异步消息传递,...
在IT行业中,面试是检验求职者技能和知识的关键环节,特别是在Java和.Net这两个热门的开发领域。本资源“面试题题库(含Java和.Net)”涵盖了这两个领域中经常出现的面试题目,对于准备面试的程序员来说是一份非常有...
在Java中,Socket类位于`java.net`包下,提供TCP/IP协议的网络通信功能。而在C++中,通常使用BSD Socket API进行网络编程,该API是操作系统提供的原生接口,适用于多种平台。 在Java中,非阻塞式Socket通信基于NIO...
在Java中,`java.net.Socket`类和`java.net.ServerSocket`类提供了Socket编程的基础API。`ServerSocket`用于监听客户端的连接请求,而`Socket`则用于建立客户端和服务器端的连接,进行数据传输。 然而,当并发请求...
在Java中,使用`java.net.Socket`类来创建一个Socket实例,以建立到指定服务器的连接。客户端通常需要执行以下步骤: 1. 创建`Socket`对象,指定服务器的IP地址和端口号,如`new Socket("服务器IP", 端口号)`。 2. ...
在Java中,通过`java.net.Socket`类来表示客户端,`java.net.ServerSocket`类来表示服务器端。本案例实现了基于TCP协议的Socket长连接,即客户端和服务端建立连接后,保持连接状态,进行多次数据交互而无需频繁建立...
在Java端,我们使用`java.net.Socket`和`ServerSocket`类来实现客户端和服务器端的Socket通信。客户端创建Socket实例,指定服务器的IP和端口,然后通过Socket的`getOutputStream()`和`getInputStream()`方法获取数据...
在Java中,`java.net.ServerSocket`类是服务器端使用的,它监听特定端口上的连接请求。当一个客户端(使用Socket)尝试连接到该端口时,ServerSocket会创建一个新的Socket实例来处理这个连接。这被称为“三次握手”...