socket编程(Java实现)
主要是前段时间学习的网络知识的基于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);
}
}
socket编程(Java实现)的更多相关文章
- UDP协议网络Socket编程(java实现C/S通信案例)
我的博客园:https://www.cnblogs.com/chenzhenhong/p/13825286.html 我的CSDN博客:https://blog.csdn.net/Charzous/a ...
- socket编程-java
一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...
- Java:基于TCP协议网络socket编程(实现C/S通信)
目录 一.前言:TCP原理简介 二.Socket编程通信 三.TCP服务器端(具体代码) 四.TCP客户端(具体代码) 五.通信效果演示 六."创意"机器人:价值一个亿的AI核心代 ...
- java多线程实现TCP网络Socket编程(C/S通信)
目录 开篇必知必会 一.多线程技术 二.实现多线程接收 1.单线程版本 2.多线程版本 三.多线程与进程的关系 四.客户端界面完整代码 五.多线程通信对比 最后 开篇必知必会 在前一篇<Java ...
- java socket编程(li)
一.网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以 ...
- 【JAVA】Socket 编程
对于Java Socket编程而言,有两个概念,一个是ServerSocket,一个是Socket.服务端和客户端之间通过Socket建立连接,之后它们就可以进行通信了.首先ServerSocket将 ...
- java socket编程(网络编程)
一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...
- JAVA Socket 编程学习笔记(二)
在上一篇中,使用了 java Socket+Tcp/IP 协议来实现应用程序或客户端--服务器间的实时双向通信,本篇中,将使用 UDP 协议来实现 Socket 的通信. 1. 关于UDP UDP协 ...
- JAVA Socket 编程学习笔记(一)
1. Socket 通信简介及模型 Java Socket 可实现客户端--服务器间的双向实时通信.java.net包中定义的两个类socket和ServerSocket,分别用来实现双向连接的cli ...
- Java Socket编程
Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而在网络编程中,使用最多的就是Socket.像大家熟悉的QQ.MSN都使用了Socket相关的技术. ...
随机推荐
- Python基础第八天
一.内容
- css层叠上下文和层叠顺序
普通元素的层叠水平优先由层叠上下文决定,因此,层叠水平的比较只有在当前层叠上下文元素中才有意义. 诸位千万不要把层叠水平和CSS的z-index属性混为一谈.没错,某些情况下z-index确实可以影响 ...
- Entity Framework Code First 迁移
Entity Framework CodeFirst数据迁移 http://www.cnblogs.com/aehyok/p/3325459.html Entity Framework Code Fi ...
- HDU 4891 The Great Pan (题意题+模拟)
题意:给定一个文章,问你有多少种读法,计算方法有两种,如果在$中,如果有多个空格就算n+1,如果是一个就算2的次方,如果在{}中, 那么就是把每个空格数乘起来. 析:直接模拟,每次计算一行,注意上一行 ...
- bzoj 1556: 墓地秘密【状压dp+spfa】
显然是状压,显然不可能把所有格子压起来 仔细观察发现只有机关周围的四个格子有用以及起点,所以我们用spfa处理出这些格子两两之间的距离(注意细节--这里写挂了好几次),然后设f[s][i]为碰完的机关 ...
- bzoj 3270: 博物馆【dp+高斯消元】
好像是高斯消元解互相推(?)的dp的例子 首先考虑dp,设f[i][j]为一人在i一人在j的概率,点i答案显然就是f[i][i]: 然后根据题意,得到转移是 \[ f[i][j]=f[i][j]*p_ ...
- k-substrings Codeforces - 961F
不会做.. 官方题解: 1.枚举某个前缀(指题目要求的相同前后缀中的前缀)的中心位置i,那么对应后缀的中心位置已经确定了(n-i+1),可以二分答案求出对于每个中心位置i最大的符合要求的相同前后缀(设 ...
- $.each遍历json对象(java将对象转化为json格式以及将json解析为普通对象)
查看一个简单的jQuery的例子来遍历一个JavaScript数组对象. var json = [ {"id":"1","tagName": ...
- [转]Resolve Team Foundation Version Control conflicts
本文转自:http://msdn.microsoft.com/en-us/library/ms181432.aspx An advantage of using Team Foundation ver ...
- 置换测试: Mock, Stub 和其他
简介 在理想情况下,你所做的所有测试都是能应对你实际代码的高级测试.例如,UI 测试将模拟实际的用户输入(Klaas 在他的文章中有讨论)等等.实但际上,这并非永远都是个好主意.为每个测试用例都访问一 ...