java socket编程测试_Java之Socket编程

本文详细介绍了Java中的Socket编程,包括基于TCP的Socket编程和基于UDP的Socket编程。TCP提供面向连接、可靠的通信,而UDP则是无连接、不可靠的数据报服务。在TCP编程中,服务器端需要创建ServerSocket并接受连接,客户端创建Socket并与服务器通信。UDP编程中,服务器和客户端的逻辑更为对等,都需要创建DatagramSocket进行数据报的收发。
摘要由CSDN通过智能技术生成

引言:

TCP/IP是一种网络通信协议,它规范了网络上所有通信设备的数据传送格式以及传送方式,是Internet上的基础协议。在TCP/IP协议组中有两种主要协议:

一)传输层协议

a)传输层控制协议(TCP)

它建立在面向连接的基础上。双方通信之前先建立连接,然后双方即可在其上发送数据流实现通信,使用完毕后再关闭连接。这种协议的优点是效率高,缺点是在建立连接关闭连接时需要额外的开销。

b)用户数据报协议(UDP)

UDP较TCP简单不少,是对IP协议组的扩充。与TCP不同,UDP是提供面向无连接、“不可靠”的数据报服务。

二)应用层协议

应用层中定义了许多高层协议。TELNET(远程终端访问)、FTP(文件传输协议)、SMTP(简单邮件传输协议)、DNS(域名服务)、HTTP(超文本传输协议)等。

Socket编程

它允许程序员把网络连接当成一个流,并向这个流读写字节。Socket对程序员隐藏了网络的低层细节,如纠错、包大小、包和重传、网络地址等。

A)基于TCP的Socket编程

需要编写服务器端和客户端两个应用程序。主要用到两个类,Socket、ServerSocket。它们都位于java.net包中。

1)服务器端编写步骤

a)创建一个等待连接的ServerSocket对象。

b)调用ServerSocket的accept方法侦听客户端的连接请求。当侦听到一个连接后,返回一个Socket对象,连接成功。

c)创建与Socket对象绑定的输入、输出流,并建立相应的数据输入输出流。

d)通过数据输入输出流与客户端进行数据读写,完成双向通信。

e)当客户端断开连接后,关闭各个流,结束通信。

f)不断执行(b~e)

请看示例代码:

import java.io.*;

import java.net.*;

import static java.lang.System.*;

public class TestServer {

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

ServerSocket ss = new ServerSocket(6666);

out.println("start......");

while(true){

Socket s = ss.accept(); // 阻塞式

err.println("a client accepted");

//建立输入流,接收客户端发来的数据

InputStream is = s.getInputStream();

DataInputStream dis = new DataInputStream(is);

out.println(dis.readUTF());// 阻塞式

//建立输出流,向客户端发送数据

OutputStream os = s.getOutputStream();

DataOutputStream dos = new DataOutputStream(os);

dos.writeUTF("Server:hello client!...");

in.close();

out.close();

ss.close();

}

}

}

2)客户端编写步骤

a)创建指定服务器上指定端口号的Socket对象

b)创建与Socket对象绑定的输入、输出流,并建立相应的数据输入输出流。

c)通过数据输入输出流与客户端进行数据读写,完成双向通信。

d)关闭与服务器的连接,关闭各个流,结束通信。

示例代码:

import java.io.*;

import java.net.*;

import static java.lang.System.*;

public class TestClient {

public static void main(String[] args) throws UnknownHostException,

IOException {

Socket s = new Socket("127.0.0.1", 6666);

OutputStream os = s.getOutputStream();

DataOutputStream dos = new DataOutputStream(os);

dos.writeUTF("client: hello server!...");

DataInputStream dis = new DataInputStream(s.getInputStream());

err.println(dis.readUTF());

}

}

B)基于UDP的Socket编程

开发基于UDP协议的网络应用程序时,也要分别编写服务器端与客户端(逻辑上的,其实两端是对等的)。与TCP不同的是这两端程序基本架构是相同的。因此对于基于UDP的Socket编程就不分服务器端与客户端。具体如下:

a)建立一个DatagramSocket对象

b)进入收发数据报包的循环,直到数据传送完毕。

1)利用DatagramSocket处理接收到的数据

2)利用DatagramSocket发送数据

c)释放Socket连接

请看示例代码:

server端:

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.SocketException;

import java.util.Date;

public class Server_udp {

public static void main(String[] args) {

try {

DatagramSocket ds = new DatagramSocket(3000);

System.out.println("waitting for connecting");

while (true) {

byte[] buf = new byte[256];

//接收

DatagramPacket p = new DatagramPacket(buf, buf.length);

ds.receive(p);

System.out.println("client:" + new String(p.getData()));

// sending for next

//发送

buf = new Date().toString().getBytes();

p = new DatagramPacket(buf, buf.length, p.getAddress(),

p.getPort());

ds.send(p);

//System.out.println("already send...");

}

} catch (SocketException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

Client端:

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

public class Client_udp {

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

DatagramSocket ds = new DatagramSocket();

// 发送

byte[] buf = new byte[256];

buf = "hello".getBytes();

DatagramPacket p = new DatagramPacket(buf, buf.length,

InetAddress.getByName("localhost"), 3000);

ds.send(p);

// 接收

p = new DatagramPacket(buf, buf.length);

ds.receive(p);

System.out.println("server:" + new String(p.getData()));

ds.close();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Socket编程中,可以使用select()方法实现多路复用的功能,以便同时处理多个Socket连接。select()方法会阻塞当前线程,直到其中一个Socket连接上有事件发生,或者超时时间到了,或者被中断。 以下是一个简单的使用select()方法的例子: ```java Selector selector = Selector.open(); ServerSocketChannel serverSocket = ServerSocketChannel.open(); serverSocket.bind(new InetSocketAddress(8080)); serverSocket.configureBlocking(false); serverSocket.register(selector, SelectionKey.OP_ACCEPT); while (true) { selector.select(); // 阻塞当前线程,直到有事件发生 Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isAcceptable()) { // 处理连接请求 SocketChannel client = serverSocket.accept(); client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { // 处理读取数据 SocketChannel client = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); int bytesRead = client.read(buffer); // 处理读取到的数据 } keyIterator.remove(); } } ``` 在上述代码中,首先创建一个Selector对象,并将ServerSocketChannel注册到Selector上,然后通过调用select()方法进行事件轮询,当有事件发生时,就可以通过SelectionKey来获取对应的Channel,并处理相应的事件。在处理完事件后不要忘记调用keyIterator.remove()方法将SelectionKey从selectedKeys集合中移除,以便下次轮询时不会重复处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值