欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Socket编程总结(1)

程序员文章站 2022-07-15 18:44:21
...

基本套接字

套接字主要是用于处理端到端数据传输,即应用程序用它来发送和接收数据。使用Socket可以将应用程序添加到网络,并与处于同一网络的其他应用程序进行通信。一台计算机上应用程序向Socket写入的信息可以被另外一台计算机的另一个应用读取。

套接字地址,包括了目的IP地址和端口号。

一、TCP套接字

Java为TCP协议提供了两个类,Socket和ServerSocket类,后者主要用于服务端,监听TCP连接请求。客户端只需要使用Socket实例进行通信,而服务端需要使用两个类的实例。典型的TCP客户端要经过以下三步:
1、创建一个Socket实例:指定IP地址和目的端口,建立一个TCP连接;
2、通过套接字(Socket实例)的输入输出流(OutputStream和InputStream)进行通信;
3、使用Socket类的close()方法关闭连接。
下面是TCP客户端的代码:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;


public class TCPEchoClient {

	public static void main(String[] args) throws IOException {
		Socket socket = new Socket("10.112.154.154",9000);
		System.out.println("正在连接服务器...");
		
		InputStream in = socket.getInputStream();
		OutputStream out = socket.getOutputStream();
		byte[] data = "send message".getBytes();
		out.write(data);
		
		int total = 0;
		int bytes;
		while(total<data.length){
			if((bytes = in.read(data,total,data.length-total))==-1)
				throw new SocketException("关闭连接");
			total += bytes;
		}
		
		System.out.println("received:" + new String(data));
		
		socket.close();
	}

}
TCP服务端则需要考虑以下几步:
1、创建一个ServerSocket并指定本地端口,该套接字功能是侦听该指定端口收到的连接;
2、重复执行:
a、调用ServerSocket的accept()方法获取下一个客户端连接,并创建Socket实例,由accept()方法返回;
b、使用返回的Socket实例的输入输出流与客户端通信;
c、通信完成后,使用Socket类的close()方法关闭该客户端套接字连接。
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 TCPEchoServer {
	
	private static final int BUFSIZE = 32;
	public static void main(String[] args) throws IOException {
		
		ServerSocket serverSocket = new ServerSocket(9000);
		
		int recvMsgSize;
		byte[] receiveBuf = new byte[BUFSIZE];
		
		while(true){
			Socket clntSocket = serverSocket.accept();
			SocketAddress clientAddress = clntSocket.getRemoteSocketAddress();
			System.out.println("在该地址处理用户请求:"+clientAddress);
			
			InputStream in = clntSocket.getInputStream();
			OutputStream out = clntSocket.getOutputStream();
			
			while ((recvMsgSize = in.read(receiveBuf)) !=-1) {
				out.write(receiveBuf,0,recvMsgSize);
			}
			clntSocket.close();
		}
	}

}

二、UDP套接字

1、UDP客户端。典型的UDP客户端主要执行以下三步:
a、创建一个DatagramSocket实例;
b、使用DatagramSocket的send()和receive()方法发送和接收DatagramSocket实例进行通信;
c、通信完成后,使用DatagramSocket类的close()方法来销毁套接字。
客户端代码如下:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPEchoClientTimeout {

	private static final int TIMEOUT = 3000;
	private static final int MAX = 5;
	public static void main(String[] args) throws IOException {
		byte[] bytesToSend = "sendsmessage".getBytes();
		DatagramSocket socket = new DatagramSocket();
		socket.setSoTimeout(TIMEOUT);
		
		InetAddress address = InetAddress.getByName("10.112.154.154");
		DatagramPacket sendPacket = new DatagramPacket(bytesToSend, bytesToSend.length,address, 9002);

		
		DatagramPacket receivePacket = new DatagramPacket(new byte[bytesToSend.length], bytesToSend.length);
		int tries = 0;
		
		boolean receivedResponse = false;
		
		do{
			socket.send(sendPacket);
			try {
				socket.receive(receivePacket);
				if(!receivePacket.getAddress().equals(address)){
					throw new IOException("接收到未知来源的消息");
				}
				receivedResponse = true;
			} catch (Exception e) {
				System.out.println(e.getMessage());
				tries += 1;
				System.out.println("超时,还有" + (MAX-tries) + "次机会");
			}
		}while((!receivedResponse) && (tries<MAX));
		
		if(receivedResponse){
			System.out.println("Received:" + new String(receivePacket.getData()));
		}else{
			System.out.println("没有接收到数据");
		}
		socket.close();
	}

}

UDP服务器端代码如下:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UDPEchoServer {

	private static final int ECHOMAX = 255;
	public static void main(String[] args) throws IOException {
		DatagramSocket socket = new DatagramSocket(9002);
		DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX);
		
		while(true){
			socket.receive(packet);
			System.out.println("在该地址处理用户请求:" + packet.getAddress().getHostAddress() + "端口号:" + packet.getPort());
			System.out.println("接收到的数据是:"+new String(packet.getData()));
			socket.send(packet);
			packet.setLength(ECHOMAX);
		}
	
	}

}