TCP和UDP套接字编程

下面会使用简单的客户机/服务器应用程序来分别演示使用TCP套接字编程和UDP套接字编程。

先说明一下,实现的功能:

(1)一台客户机从键盘读取一行字符,并通过连接的套接字发送给服务器

(2)服务器从套接字读取该行字符

(3)服务器将该行字符的小写字符,转换成大写字符

(4)服务器将转换后的字符通过连接的套接字返回给客户机

(5)客户机从其套接字读取转换后的字符后,通过监视器打印出来。

下面先看一下TCP套接字编程:

TCPServer:

public class TcpServer {
public static void main (String arg[])throws Exception{
String clientSentence;
String ModifiedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true){
Socket connectionSocket = welcomeSocket.accept();
BufferedReader isFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = isFromClient.readLine();
ModifiedSentence = clientSentence.toUpperCase()+'\n';
outToClient.writeBytes(ModifiedSentence);
		}
	}
}
ServerSocket welcomeSocket = new ServerSocket(6789);
通常我们把Socket当作一扇门,而这一句则是监听某客户机“敲门”声的门,而且是在6789端口上监听。

Socket connectionSocket = welcomeSocket.accept();

 
 这句表示,当某客户机“敲门”时,则创建一个新的套接字。这时,connectionSocket已经和客户机某socke创建了虚拟管道,它们都可以通过其发送直接。 

BufferedReader isFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
clientSentence = isFromClient.readLine();
这两行则读取了客户机的输入。

ModifiedSentence = clientSentence.toUpperCase()+'\n';
这一行完成了将客户机发来的字符,转换成大写字符

DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
outToClient.writeBytes(ModifiedSentence);
这两行则往客户机返回数据。


TCPClient:

public class TcpClient {
public static void main(String[] args)throws Exception{
String sentence;
String modifiedSentence;
BufferedReader isFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientsSocket = new Socket(InetAddress.getLocalHost(), 6789);
DataOutputStream outToServer= new DataOutputStream(clientsSocket.getOutputStream());
BufferedReader isFromServer = new BufferedReader(new InputStreamReader(clientsSocket.getInputStream()));
sentence = isFromUser.readLine();
outToServer.writeBytes(sentence+'\n');
modifiedSentence = isFromServer.readLine();
System.out.println("From Server:" + modifiedSentence);
clientsSocket.close();
}
}

BufferedReader isFromUser = new BufferedReader(new InputStreamReader(System.in));
sentence = isFromUser.readLine();

 这两行是读取用户从键盘上输入的东西,并转换成字符串类型,放在sentence。 

Socket clientsSocket = new Socket(InetAddress.getLocalHost(), 6789);
创建了与服务器连接的Socket,通过该行也发起了客户机和服务器间的TCP连接。由于本次测试是在客户机,服务器都是本主机,所以IP地址是InetAddress.getLocalHost(),即本地IP地址。6789表示连接服务器上的端口号。

DataOutputStream outToServer= new DataOutputStream(clientsSocket.getOutputStream());
outToServer.writeBytes(sentence+'\n');
这两行是把用户输入的文本发送到服务器上。

BufferedReader isFromServer = new BufferedReader(new InputStreamReader(clientsSocket.getInputStream()));
modifiedSentence = isFromServer.readLine();
System.out.println("From Server:" + modifiedSentence);
这三行是读取服务器返回的信息,并打印在监视器上。

clientsSocket.close();
该行关闭了套接字,因此客户机和服务器之间的TCP连接也同时被关闭。这一行会引起客户机向服务器发送运输层报文。


注意这里应该先运行编译好的服务器程序,在运行客户机的程序,结果如下:

假设输入为abc

abc
From Server:ABC

然后用UDP套接字编程实现同样的功能:

UDPServer:

public class UDPServer {
	public static void main(String args[]) throws Exception {
		DatagramSocket serverSocket = new DatagramSocket(9999);
		byte[] receiveData = new byte[1024];
		byte[] sendData = new byte[1024];
		while (true) {
			DatagramPacket receivePacket = new DatagramPacket(receiveData,
					receiveData.length);
			serverSocket.receive(receivePacket);
			String sentence = new String(receivePacket.getData());
			InetAddress ipAddress = receivePacket.getAddress();
			int port = receivePacket.getPort();
			String modifiedSentence = sentence.toUpperCase();
			sendData = modifiedSentence.getBytes();
			DatagramPacket sendDatagramPacket = new DatagramPacket(sendData,
					sendData.length, ipAddress, port);
			serverSocket.send(sendDatagramPacket);
		}
	}
}

DatagramSocket serverSocket = new DatagramSocket(9999);
该行在端口9999构造了DatagramSocket对象,应该注意到这用到的套接字与TCP不一样。因为UDP是无连接的,所以当接受时,没有必要像TCP那样产生一个新的套接字并继续监听请求。如果有多个客户机访问该服务器端口,都将往这个单一的门发送分组。

DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
这几行是读取客户机发送过来的数据,并放在sentence上。

InetAddress ipAddress = receivePacket.getAddress();
<pre name="code" class="java">int port = receivePacket.getPort();

 这一行是获取客户机的ip地址和端口。以便给客户机返回数据。 

DatagramPacket sendDatagramPacket = new DatagramPacket(sendData,sendData.length, ipAddress, port);
serverSocket.send(sendDatagramPacket);
这两行则是把转换结果发送给客户机。注意该分组应该包含IP地址与端口。


UDPClient:

public class UDPClient {
	public static void main(String args[])throws Exception{
		BufferedReader isFromUser = new BufferedReader(new InputStreamReader(System.in));
		DatagramSocket clientSocket = new DatagramSocket(11111);
		byte[] sendData = new byte[1024];
		byte[] receiveData = new byte[1024];
		String sentence = isFromUser.readLine();
		sendData = sentence.getBytes();
		DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getLocalHost(), 9999);
		clientSocket.send(sendPacket);
		DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
		clientSocket.receive(receivePacket);
		String modifiedSentence = new String(receivePacket.getData());
		System.out.println("From Server:"+modifiedSentence);
		clientSocket.close();
	}
}

DatagramSocket clientSocket = new DatagramSocket(11111);
该行,是为UDP套接字指派了一个特定的端口号11111,当然也可以不指定端口号,则不填参数即可,这时,运输层自动为该套接字分配一个尚未使用的端口号。

DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getLocalHost(), 9999);
该行构件了一个分组,包含数据,数据长度,服务器IP地址(因为本测试在本主机运行,所以用本地IP地址),以及端口号

clientSocket.close();
关闭套接字,因为UDP无连接的,所以不会引起客户机向服务器发送运输层报文。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值