首页 技术 正文
技术 2022年11月14日
0 收藏 529 点赞 4,931 浏览 9358 个字

主要是前段时间学习的网络知识的基于TCP与UDP编程,Java实现简单的大小写字母的转化,该文主要参考:

https://blog.csdn.net/yjp19871013/article/details/53537398

UDP服务端代码:

 public class ToUpperUDPServer {     //服务器的IP
public static final String SERVER_IP = "127.0.0.1"; //服务器端的端口号 最好是大于2000 不要选取那些特殊的端口号 Oracle:1521 MySQL:3306 Tomcat:8080
public static final int SERVER_PORT = 10005; //最大的传输字节数
public static final int MAX_BYTES = 1024; //UDP使用DatagramSocket发送数据包
private DatagramSocket serverSocket; /**
* 启动服务器
* @param serverIp 服务器的IP地址
* @param serverPort 服务器的端口号
*/
public void startServer(String serverIp, int serverPort){ try {
//创建DatagramSocket
InetAddress serverAddr = InetAddress.getByName(serverIp);
serverSocket = new DatagramSocket(serverPort, serverAddr); //创建接受服务的对象
byte[] recvBuf = new byte[MAX_BYTES];
DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length); //死循环,一直运行服务器
while(true){ System.out.println("服务端正在接收数据,接收的数据包为:"+recvPacket);
//接受数据,会在这里堵塞,直达数据到来
serverSocket.receive(recvPacket);
String receStr = new String(recvPacket.getData(), 0 , recvPacket.getLength()); //获取连接端的IP和端口号port
InetAddress clientAddr = recvPacket.getAddress();
int clientPort = recvPacket.getPort(); //回传数据
String upperStr = receStr.toUpperCase();
byte[] sendBuf = upperStr.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, clientAddr, clientPort); System.out.println("服务端正在发送数据,发送的数据包为:"+sendPacket);
//服务器Socket 发送数据
serverSocket.send(sendPacket);
} } catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) {
ToUpperUDPServer server = new ToUpperUDPServer();
server.startServer(SERVER_IP, SERVER_PORT);
}
}

UDP客户端代码:

 public class ToUpperUDPClient {     //创建连接的DatagramSocket
private DatagramSocket clientSocket; public String toUpperRemote(String serverIp, int serverPort, String str){ String recvStr = ""; try {
//创建 UDP socket
clientSocket = new DatagramSocket(); byte[] sendBuf = str.getBytes();
InetAddress serverAddr = InetAddress.getByName(serverIp);
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, serverAddr, serverPort);
clientSocket.send(sendPacket);
System.out.println("客户端正在发送数据,发送的数据包为:" + sendPacket); //接收服务器的响应
byte[] recvBuf = new byte[ToUpperUDPServer.MAX_BYTES];
DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
clientSocket.receive(recvPacket);
System.out.println("客户端正在接收服务器的响应,接收的数据包为:" + recvPacket); //显示响应
recvStr = new String(recvPacket.getData(), 0 , recvPacket.getLength()); } catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(null != clientSocket){
clientSocket.close();
clientSocket = null;
}
}
return recvStr;
} public static void main(String[] args) { ToUpperUDPClient client = new ToUpperUDPClient();
String recvStr = client.toUpperRemote(ToUpperUDPServer.SERVER_IP, ToUpperUDPServer.SERVER_PORT, "aaaAAAbbbBBBcccCCC");
System.out.println("客户端收到的数据:" + recvStr);
}
}

TCP服务端有三种模式:

1、基于TCP协议阻塞式服务

 public class ToUpperTCPBlockServer {     //服务端的IP地址
public static final String SERVER_IP = "127.0.0.1"; //服务端的端口号
public static final int SERVER_PORT = 10005; //请求终结字符串
public static final char REQUEST_END_CHAR = '#'; /***
* 开启服务
* @param serverIp 服务端ip地址
* @param serverPort 服务端端口号
*/
public void startServer(String serverIp, int serverPort){ try {
//创建服务器地址对象
InetAddress serverAddr = InetAddress.getByName(serverIp); //Java提供了ServerSocket作为服务器
//楼主使用了Java的自动关闭的语法, 这个自动关闭语法是JDK1.7中的,我这里是正常写法
ServerSocket serverSocket = new ServerSocket(SERVER_PORT, 5, serverAddr); while(true){ StringBuilder recvStrBuilder = new StringBuilder(); //有客户端向服务器发起tcp连接时,accept会返回一个Socket
//该Socket的対端就是客户端的Socket
//具体过程可以查看TCP三次握手过程
Socket connection = serverSocket.accept();
InputStream in = connection.getInputStream(); //读取客户端的请求字符串,请求字符以#结尾
for(int c=in.read(); c!=REQUEST_END_CHAR; c=in.read()){
recvStrBuilder.append((char) c);
}
recvStrBuilder.append("#");
String recvStr = recvStrBuilder.toString(); //向客户端写出处理过的字符串
OutputStream os = connection.getOutputStream();
os.write(recvStr.toUpperCase().getBytes());
} } catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) {
ToUpperTCPBlockServer server = new ToUpperTCPBlockServer();
System.out.println("服务器端开始接收请求...");
server.startServer(SERVER_IP, SERVER_PORT);
}
}

2、基于TCP的并发服务器

 public class ToUpperTCPThreadServer {     //服务器对外的ip
public static final String SERVER_IP = "127.0.0.1"; //服务器端口号
public static final int SERVER_PORT = 10005; //请求中介字符串
public static final char REQUEST_END_CHAR = '#'; /***
* 开启服务
* @param serverIp 服务端ip
* @param serverPort 服务端端口号
*/
public void startServer(String serverIp, int serverPort){ try {
InetAddress serverAddr = InetAddress.getByName(serverIp);
ServerSocket serverScoket = new ServerSocket(SERVER_PORT, 5 ,serverAddr); //创建线程池
Executor executor = Executors.newFixedThreadPool(100); //保持服务一直处于开启的状态
while(true){
final StringBuilder recvStrBuilder = new StringBuilder(); //有客户向服务器发起TCP连接时,accept会返回一个socket
//该socket的对端就是客户端的socket
//具体情况可以查看socket的三次握手情况
final Socket connection = serverScoket.accept(); //利用线程池,启动线程
executor.execute(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Socket conn = connection;
try {
InputStream in = conn.getInputStream();
for(int c=in.read(); c!=REQUEST_END_CHAR; c=in.read()){
recvStrBuilder.append((char) c);
}
recvStrBuilder.append('#');
String resvStr = recvStrBuilder.toString(); ////向客户端写出处理后的字符串
OutputStream os = connection.getOutputStream();
os.write(resvStr.toUpperCase().getBytes()); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(conn != null){
try {
conn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
} } catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) {
ToUpperTCPThreadServer server = new ToUpperTCPThreadServer();
server.startServer(SERVER_IP, SERVER_PORT);
}
}

3、第三种

 public class ToUpperTCPNonBlockServer {     //服务器对外的ip
public static final String SERVER_IP = "127.0.0.1"; //服务器端口号
public static final int SERVER_PORT = 10005; //请求中介字符串
public static final char REQUEST_END_CHAR = '#'; /**
* 开启服务
* @param serverIp 服务器对外的ip
* @param serverPort 服务器端端口号
*/
public void startServer(String serverIp, int serverPort){ try {
//使用NIO 需要用到ServerSocketChannel 其中包含一个serverSocket对象
ServerSocketChannel serverChannel = ServerSocketChannel.open();
//创建地址对象
InetSocketAddress localAddr = new InetSocketAddress(SERVER_IP,SERVER_PORT);
//服务器绑定地址
serverChannel.bind(localAddr);
//设置为非堵塞
serverChannel.configureBlocking(false); //注册到Selector 会ServerSocket的accept
//我们用Selector监听accept是否返回
//当调用accept卡伊返回时,会得到通知
//注意是可以返回,还需要调用accept
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT); //服务一直处于启动状态,所以这个是死循环
while(true){
//调用select,阻塞在这里,直到有注册的channel满足条件
selector.select(); //如果走到这里,有符合条件的channel
//可以通过selector.selectedKeys().iterator()得到符合条件的迭代器
Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); //处理得到的keys
while(keys.hasNext()){ //取出一个key 并移除
SelectionKey key = keys.next();
keys.remove();
try{
if(key.isAcceptable()){
//有accept返回,取出可以使用的channel
ServerSocketChannel server = (ServerSocketChannel) key.channel(); //调用accept三次握手 返回与客户端可以通信的channel
SocketChannel channel = server.accept(); //将该channel 置为非堵塞
channel.configureBlocking(false); //注册此selector 当可读或可写时将得到通知,select返回
channel.register(selector, SelectionKey.OP_READ);
}else if(key.isReadable()){
//有channel可读 取出可读的channel
SocketChannel channel = (SocketChannel) key.channel(); //创建读取缓冲区,一次读取1024字节
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer); //锁住缓冲区,缓冲区的大小将固定
buffer.flip(); //附件上buffer 供写出使用
key.attach(buffer);
key.interestOps(SelectionKey.OP_WRITE);
}else if(key.isWritable()){
//有channel可写,取出可写的channel
SocketChannel channel = (SocketChannel) key.channel(); //取出可读时设置的缓冲区
ByteBuffer buffer = (ByteBuffer) key.attachment(); //将缓冲区的指针移动到缓冲区开始的位置
buffer.rewind(); //读取为String
String recv = new String(buffer.array()); //清空缓冲区
buffer.clear();
buffer.flip(); //写回数据
byte[] sendByte = recv.toUpperCase().getBytes();
channel.write(ByteBuffer.wrap(sendByte)); //变为等待者
key.interestOps(SelectionKey.OP_READ);
}
}catch(Exception e){
key.cancel();
key.channel().close();
e.printStackTrace();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main (String[] args){
ToUpperTCPBlockServer server = new ToUpperTCPBlockServer();
server.startServer(SERVER_IP, SERVER_PORT);
}
}

TCP客户端:

 public class ToUpperTCPClient {     //客户端的请求的 TCP socket
private Socket clientSocket; public String toUpperRemote(String serverIp, int ServerPort, String str){ StringBuilder recvStrBuilder = new StringBuilder(); try {
//创建连接服务器的socket
clientSocket = new Socket(serverIp, ServerPort); //写出请求的字符串
OutputStream os = clientSocket.getOutputStream();
os.write(str.getBytes()); //读取服务器响应
InputStream in = clientSocket.getInputStream();
for(int c=in.read(); c!='#'; c=in.read()){
recvStrBuilder.append((char) c);
} } catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(clientSocket != null){
try {
clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return recvStrBuilder.toString();
} public static void main(String[] args) {
ToUpperTCPClient client = new ToUpperTCPClient();
String recvStr = client.toUpperRemote(ToUpperTCPBlockServer.SERVER_IP, ToUpperTCPBlockServer.SERVER_PORT,"aaaAAAbbbBBBcccCCC" + ToUpperTCPBlockServer.REQUEST_END_CHAR);
System.out.println("收到:" + recvStr);
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,491
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,492
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,294