TCP 编程
- 传输单位为字节
- 客户端:socket = new Socket(server, servPort);
- 服务器:
- serverSocket = new ServerSocket(serverPort);
- Socket clientSocket = serverSocket.accept();
- TCPSocketServer:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
public class TCPSocketServer {
public static void main(String[] args) {
run();
}
public static void run() {
// socket指定端口号,0-65535,不能与其他进程端口号冲突,否则启动会端口占用的错误
int serverPort = 4700;
// 创建服务端socket
ServerSocket serverSocket;
int receiveMsgSize;
// 接收字节缓冲数组
byte[] receiveMsgBuffer = new byte[32];
try {
serverSocket = new ServerSocket(serverPort);
// 处理完一个客户端请求之后再次进入等待状态
while (true) {
// 程序执行到这之后,将一直等待客户端连接,直到有客户端接入,代码才继续执行
System.out.println("服务端已启动,绑定端口" + serverPort);
Socket clientSocket = serverSocket.accept();
SocketAddress clientAddress = clientSocket
.getRemoteSocketAddress();
System.out.println("收到客户端连接,ip:" + clientAddress);
InputStream in = clientSocket.getInputStream();
OutputStream out = clientSocket.getOutputStream();
// 接收客户端发来的数据,并原样返回给客户端
while ((receiveMsgSize = in.read(receiveMsgBuffer)) != -1) {
String receivedData = new String(receiveMsgBuffer);
System.out.println(receivedData);
receivedData = receivedData.toUpperCase();
out.write(receivedData.getBytes(), 0, receiveMsgSize);
}
// 释放socket资源
clientSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class TCPSocketClient {
public static void main(String[] args) {
String host = "localhost";
int port = 4700;
String sendMsg = "send data from client";
connect(host, port, sendMsg.getBytes());
}
public static void connect(String server, int servPort, byte[] data) {
// 创建socket对象用于连接服务端socket
Socket socket = null;
try {
socket = new Socket(server, servPort);
System.out.println("连接服务器并发送数据...");
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
out.write(data);
// 接收数据
// 目前收到的总字节长度
int totalBytesRcvd = 0;
// 最后一次读取的字节长度
int bytesRcvd;
// 将服务器返回消息读到data字节数组中
while (totalBytesRcvd < data.length) {
bytesRcvd = in.read(data, totalBytesRcvd, data.length
- totalBytesRcvd);
if (bytesRcvd == -1) {
throw new SocketException("连接中断...");
}
totalBytesRcvd += bytesRcvd;
}
System.out.println("接收的数据:" + new String(data));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {// 关闭socket资源
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
UDP 编程
- 传输单位为 packet
- 首先创建 DatagramSocket 对象,再创建 DatagramPacket 对象用于接收或者发送
- UDPSocketServer:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UDPSocketServer {
public static void main(String[] args) {
receive();
}
public static void receive() {
System.out.println("接收端启动");
// 接收端
try {
// 创建接收方的套接字对象,并与send方法中DatagramPacket的ip地址与端口号一致
DatagramSocket socket = new DatagramSocket(9001,
InetAddress.getByName("localhost"));
// 接收数据的buf数组并指定大小
byte[] buf = new byte[1024];
// 创建接收数据包,存储在buf中
DatagramPacket packet = new DatagramPacket(buf, buf.length);
// 接收操作,代码会停顿在这里,直到接收到数据包
socket.receive(packet);
byte data[] = packet.getData();// 接收的数据
InetAddress address = packet.getAddress();// 接收的地址
System.out.println("接收的文本==>" + new String(data));
System.out.println("接收的ip地址==>" + address.toString());
System.out.println("接收的端口==>" + packet.getPort());
// 告诉发送者 接收完毕了
String temp = "接收端接收完毕了";
byte buffer[] = temp.getBytes();
// 创建数据报,指定发送给发送者的socketAddress地址
DatagramPacket packet2 = new DatagramPacket(buffer, buffer.length,
packet.getSocketAddress());
// 发送
socket.send(packet2);
// 关闭
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UDPSocketClient {
public static void main(String[] args) {
send();
}
// 发送者发给接收端数据,接收端返回数据给发送者
public static void send() {
System.out.println("发送端发送数据");
// 发送端
try {
// 创建发送方的套接字 对象 采用9004默认端口号
DatagramSocket socket = new DatagramSocket(9004);
// 发送的内容
String text = "hello from sender!";
byte[] buf = text.getBytes();
// 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
DatagramPacket packet = new DatagramPacket(buf, buf.length,
InetAddress.getByName("localhost"), 9001);
// 从此套接字发送数据报包
socket.send(packet);
// 接收,接收者返回的数据
displayReceiveInfo(socket);
// 关闭此数据报套接字。
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 接收数据并打印出来
*
* @param socket
* @throws IOException
*/
public static void displayReceiveInfo(DatagramSocket socket)
throws IOException {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
byte data[] = packet.getData();// 接收的数据
InetAddress address = packet.getAddress();// 接收的地址
System.out.println("接收的文本==>" + new String(data));
System.out.println("接收的ip地址==>" + address.toString());
System.out.println("接收的端口==>" + packet.getPort());
}
}