- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
网络编程 : 指网络上的主机,通过不同的进程,以编程的方式实现网络通信.
简单来说: 网络编程就是通过代码的方式来控制不同进程间能够进行数据交互.
发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机。
接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目的主机。
收发端:发送端和接收端两端,也简称为收发端
请求(Request) : 客户端给服务端发送的数据
响应(Response) : 服务端给客户端返回的数据
客户端 : 主动发送请求的一方
服务端 : 被动接受请求的一方
客户端和服务端的交互方式:
Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程.
TCP协议,(Transmission Control Protocol)
TCP的特点:
UDP协议,(User Datagram Protocl)
UDP的特点:
DatagramSocket
是UDP Socket, 用于发送和接收UDP数据报.
方法签名 | 方法说明 |
---|---|
DatagramSocket() | 创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端) |
DatagramSocket(int port) | 创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端) |
方法签名 | 方法说明 |
---|---|
void receive(DatagramPacket p) | 从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待) |
void send(DatagramPacket p) | 从此套接字发送数据报包(不会阻塞等待,直接发送) |
void close() | 关闭此数据报套接字 |
DatagramPacket
是UDP Socket发送和接收的数据报.
方法签名 | 方法说明 |
---|---|
DatagramPacket(byte[] buf, int length) | 构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组(第一个参数buf)中,接收指定长度(第二个参数length) |
DatagramPacket(byte[] buf, int offset, int length,SocketAddress address) | 构造一个DatagramPacket以用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从0到指定长度(第二个参数length)。address指定目的主机的IP和端口号 |
方法签名 | 方法说明 |
---|---|
InetAddress getAddress() | 从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址 |
int getPort() | 从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号 |
byte[] getData() | 获取数据报中的数据 |
注: 构造UDP发送的数据报时,需要传入 SocketAddress
,该对象可以使用 InetSocketAddress
来创建。InetSocketAddress
的构造方法
方法签名 | 方法说明 |
---|---|
InetSocketAddress(InetAddress addr, int port) | 创建一个Socket地址,包含IP地址和端口号 |
代码示例: UdpServer
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
private DatagramSocket socket = null;
public UdpEchoServer(int port) throws SocketException {
this.socket = new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动!");
while (true) {
// 1. 读取请求 并 解析
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(),0, requestPacket.getLength());
// 2. 根据请求计算响应
String response = process(request);
// 3. 把响应写回到客户端
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
requestPacket.getSocketAddress());
socket.send(responsePacket);
// 4. 打印日志
String log = String.format("[%s:%d] req: %s; resp: %s",requestPacket.getAddress().toString(),
requestPacket.getPort(),request,response);
System.out.println(log);
}
}
private String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer server = new UdpEchoServer(9090);
server.start();
}
}
代码示例: UdpClient
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
private DatagramSocket socket = null;
private String serverIp;
private int serverPort;
public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
this.serverIp = serverIp;
this.serverPort = serverPort;
this.socket = new DatagramSocket();
}
public void start() throws IOException {
while (true) {
// 1. 读取输入数据
System.out.print("->");
Scanner sc = new Scanner(System.in);
String request = sc.next();
if(request.equals("exit")){
System.out.println("exit");
break;
}
// 2. 构造请求 并 发送给服务器
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),0,request.getBytes().length,
InetAddress.getByName(serverIp),serverPort);
socket.send(requestPacket);
// 3. 读取服务器的响应 并 解析
DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
String response = new String(responsePacket.getData(),0, responsePacket.getLength());
// 4.显式给用户
String log = String.format("req: %s; resp: %s",request,response);
System.out.println(log);
}
}
public static void main(String[] args) throws IOException {
UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
client.start();
}
}
运行结果:
客户端 输入需要查找的英文的请求
客户端 返回对应的英文翻译的响应
代码示例: UdpServer
package Translation;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
public class UdpTranslateServer {
private DatagramSocket socket = null;
private Map<String,String> map = new HashMap<>();
public UdpTranslateServer(int port) throws SocketException {
this.socket = new DatagramSocket(port);
map.put("translate","翻译");
map.put("china","中国");
map.put("hello","你好");
}
public void start() throws IOException {
System.out.println("服务器启动!");
while (true) {
// 1. 读取请求并解析
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(),0, requestPacket.getLength());
// 2. 根据请求计算响应
String response = process(request);
// 3. 把响应写回给客户端
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
requestPacket.getSocketAddress());
socket.send(responsePacket);
// 4. 打印日志
String log = String.format("[%s:%d] req: %s; resp: %s",requestPacket.getAddress().toString(),
requestPacket.getPort(),request,response);
System.out.println(log);
}
}
private String process(String request) {
return map.getOrDefault(request,"查无此单词");
}
public static void main(String[] args) throws IOException {
UdpTranslateServer server = new UdpTranslateServer(9090);
server.start();
}
}
代码示例: UDPClient
package Translation;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpTranslateClient {
private DatagramSocket socket = null;
private String serverIp;
private int serverPort;
public UdpTranslateClient (String serverIp,int serverPort) throws SocketException {
this.serverIp = serverIp;
this.serverPort = serverPort;
socket = new DatagramSocket();
}
public void start() throws IOException {
while (true) {
System.out.print("->");
Scanner sc = new Scanner(System.in);
// 1. 根据用户的输入 构造请求
String request = sc.next();
if(request.equals("exit")){
System.out.println("exit!");
return;
}
// 2. 发送请求给服务器
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
InetAddress.getByName(serverIp),serverPort);
socket.send(requestPacket);
// 3. 读取服务器的响应
DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
String response = new String(responsePacket.getData(),0, responsePacket.getLength());
System.out.println(response);
// 4. 解析响应并显式
String log = String.format("req: %s; resp: %s",request,response);
System.out.println(log);
}
}
public static void main(String[] args) throws IOException {
UdpTranslateClient client = new UdpTranslateClient("127.0.0.1",9090);
client.start();
}
}
运行结果:
方法签名 | 方法说明 |
---|---|
ServerSocket(int port) | 创建一个服务端流套接字Socket,并绑定到指定端口 |
方法签名 | 方法说明 |
---|---|
Socket accept() | 开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待 |
void close() | 关闭此套接字 |
方法签名 | 方法说明 |
---|---|
Socket(String host, int port) | 创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接 |
方法签名 | 方法说明 |
---|---|
InetAddress getInetAddress() | 返回套接字所连接的地址 |
InputStream getInputStream() | 返回此套接字的输入流 |
OutputStream getOutputStream() | 返回此套接字的输出流 |
ServerSocket
关联上一个端口号调用 ServerSocket
的 accept
方法
目的是 建立连接
会返回一个 Socket
实例,称为 clientSocket
使用 clientSocket
的 getInputStream
和 getOutputStream
得到字节流对象,进行读写和写入
读取请求 并 解析
根据请求计算响应
把响应写回客户端
打印日志
当客户端断开连接之后,服务器就应该要及时的关闭 clientSocket
. (防止出现文件泄露的情况)
Socket
对象.创建的同时指定服务器的 ip 和端口客户端就可以通过 Socket
对象的 getInputStream
和 getOutputStream
来和服务器进行通信
从键盘上,读取用户输入的内容
把这个读取的内容构造成请求,发送给服务端
从服务器读取响应并解析
把结构显示到界面上
这里的是普通版本 不能处理多个客户端
代码示例: TCPClient
package TCP;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TcpEchoClient {
private Socket socket = null;
private String serverIp;
private int serverPort;
public TcpEchoClient(String serverIp,int serverPort) throws IOException {
this.serverIp = serverIp;
this.serverPort = serverPort;
// 让 socket 创建的同时,就和服务器尝试建立连接
this.socket = new Socket(serverIp,serverPort);
}
public void start() {
Scanner scanner = new Scanner(System.in);
try(InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream()){
while (true) {
// 1. 从键盘上,读取用户输入的内容
System.out.print("->");
String request = scanner.next();
if (request.equals("exit")){
break;
}
// 2. 把这个读取的内容构造成请求,发送给服务器
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println(request);
printWriter.flush();
// 3. 从服务器读取响应并解析
Scanner respScanner = new Scanner(inputStream);
String response = respScanner.next();
// 4. 把结果显示到界面上
String log = String.format("req: %s; resp: %s",request,response);
System.out.println(log);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
TcpEchoClient client = new TcpEchoClient("127.0.0.1",9090);
client.start();
}
}
代码示例: TCPServer
package TCP;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TcpEchoServer {
private ServerSocket listenSocket = null;
public TcpEchoServer(int port) throws IOException {
listenSocket = new ServerSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动!");
while (true) {
// 1. 建立连接
Socket clientSocket = listenSocket.accept(); // 没有客户端来就会 阻塞等待
processConnection(clientSocket);
}
}
private void processConnection(Socket clientSocket) throws IOException {
String log = String.format("[%s:%d] 客户端上线!",
clientSocket.getInetAddress().toString(),clientSocket.getPort());
System.out.println(log);
try(InputStream inputStream = clientSocket.getInputStream();
OutputStream outputStream = clientSocket.getOutputStream()) {
while (true) {
// 1. 读取请求并解析
Scanner scanner = new Scanner(inputStream);
if(!scanner.hasNext()){
log = String.format("[%s:%d] 客户端下线",clientSocket.getInetAddress().toString(),clientSocket.getPort());
System.out.println(log);
break;
}
String request = scanner.next();
// 2. 根据请求计算响应
String response = process(request);
// 3. 把响应写回给客户端
PrintWriter writer = new PrintWriter(outputStream);
writer.println(response);
writer.flush();
log = String.format("[%s:%d] req: %s; resp: %s",clientSocket.getInetAddress().toString(),
clientSocket.getPort(),request,response);
System.out.println(log);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
clientSocket.close();
}
}
private String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
TcpEchoServer server = new TcpEchoServer(9090);
server.start();
}
}
多线程版本,能处理多个客户端,但是需要频繁的创建销毁线程
代码示例 TCPServer (客户端一致)
package TCPThread;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TcpThreadEchoServer {
private ServerSocket listenSocket = null;
public TcpThreadEchoServer(int port) throws IOException {
listenSocket = new ServerSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动!");
while (true) {
Socket clientSocket = listenSocket.accept();
// 创建一个线程来给这个客户提供服务
Thread t = new Thread(){
@Override
public void run() {
try {
processConnection(clientSocket);
} catch (IOException e) {
e.printStackTrace();
}
}
};
t.start();
}
}
public void processConnection(Socket clientSocket) throws IOException {
// 1. 打印日志
String log = String.format("[%s,%d] 客户端上线",clientSocket.getInetAddress().toString(),clientSocket.getPort());
System.out.println(log);
try (InputStream inputStream = clientSocket.getInputStream();
OutputStream outputStream = clientSocket.getOutputStream()){
while (true) {
// 1. 读取 请求 并 解析
Scanner sc = new Scanner(inputStream);
if(!sc.hasNext()){
log = String.format("[%s,%d] 客户端下线",clientSocket.getInetAddress().toString(),clientSocket.getPort());
System.out.println(log);
break;
}
String request = sc.next();
// 2. 根据请求计算响应
String response = process(request);
// 3. 把响应写回客户端
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println(response);
printWriter.flush();
// 4. 打印日志
log = String.format("[%s:%d] req: %s; resp: %s",clientSocket.getInetAddress().toString(),
clientSocket.getPort(),request,response);
System.out.println(log);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
clientSocket.close();
}
}
public String process(String request){
return request;
}
public static void main(String[] args) throws IOException {
TcpThreadEchoServer server = new TcpThreadEchoServer(9090);
server.start();
}
}
由于多线程版的创建销毁线程的开销太大,这里使用线程池的方法.
package TCPThread;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TcpThreadPoolEchoServer {
private ServerSocket listenSocket = null;
public TcpThreadPoolEchoServer(int port) throws IOException {
listenSocket = new ServerSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动");
ExecutorService executorService = Executors.newCachedThreadPool();
while (true) {
Socket clientSocket = listenSocket.accept();
// 使用线程池 来 处理当前的 processConnextion
executorService.submit(()-> {
try {
processConnection(clientSocket);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
public void processConnection(Socket clientSocket) throws IOException {
// 1. 打印日志
String log = String.format("[%s,%d] 客户端上线",clientSocket.getInetAddress().toString(),clientSocket.getPort());
System.out.println(log);
try (InputStream inputStream = clientSocket.getInputStream();
OutputStream outputStream = clientSocket.getOutputStream()){
while (true) {
// 1. 读取 请求 并 解析
Scanner sc = new Scanner(inputStream);
if(!sc.hasNext()){
log = String.format("[%s,%d] 客户端下线",clientSocket.getInetAddress().toString(),clientSocket.getPort());
System.out.println(log);
break;
}
String request = sc.next();
// 2. 根据请求计算响应
String response = process(request);
// 3. 把响应写回客户端
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println(response);
printWriter.flush();
// 4. 打印日志
log = String.format("[%s:%d] req: %s; resp: %s",clientSocket.getInetAddress().toString(),
clientSocket.getPort(),request,response);
System.out.println(log);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
clientSocket.close();
}
}
public String process(String request){
return request;
}
}
运行结果
代码示例: TCPServer (这里的客户端还是跟前面一样)
package Translation;
import TCPThread.TcpThreadPoolEchoServer;
import java.io.IOException;
import java.util.HashMap;
// echo 和 translate 两个服务器之间,大多都是类似的
public class TcpTranslateServer extends TcpThreadPoolEchoServer {
private HashMap<String,String> map = new HashMap<>();
public TcpTranslateServer(int port) throws IOException {
super(port);
map.put("china","中国");
map.put("hello","你好");
map.put("translate","翻译");
}
@Override
public String process(String request) {
return map.getOrDefault(request,"查无此单词!");
}
public static void main(String[] args) throws IOException {
TcpTranslateServer server = new TcpTranslateServer(9090);
server.start();
}
}
运行结果:
我们自定义协议
请求 : 字符串类型 操作数1;操作数2;运算符
响应 : 字符串类型 计算响应
package Calculator;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class CalcServer {
private DatagramSocket socket = null;
public CalcServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动!");
while (true){
// 1. 读取请求并解析
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(),0,requestPacket.getLength());
// 2. 跟据请求计算响应
String response = process(request);
// 3. 把响应写回给客户端
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
requestPacket.getSocketAddress());
socket.send(responsePacket);
// 4. 打印日志
String log = String.format("[%s:%d] req: %s; resp: %s",requestPacket.getAddress().toString(),
requestPacket.getPort(),request,response);
System.out.println(log);
}
}
private String process(String request) {
// 分离
String[] str = request.split(";");
if(str.length != 3) return "[请求的格式出错!]";
int num1 = Integer.parseInt(str[0]);
int num2 = Integer.parseInt(str[1]);
if(str[2].equals("+")){
return num1+num2+"";
}else if(str[2].equals("-")){
return num1-num2+"";
}else if(str[2].equals("*")){
return (num1 * num2)+"";
}else if(str[2].equals("/")){
return (num1 / num2)+"";
}
return "[请求格式出错!操作符不支持!]";
}
public static void main(String[] args) throws IOException {
CalcServer server = new CalcServer(9090);
server.start();
}
}
package Calculator;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;
public class CalcClient {
private String serverIp;
private int serverPort;
private DatagramSocket socket = null;
public CalcClient(String serverIp,int serverPort) throws SocketException {
this.serverIp = serverIp;
this.serverPort = serverPort;
socket = new DatagramSocket();
}
public void start() throws IOException {
Scanner sc = new Scanner(System.in);
while (true) {
// 1. 用户输入的请求
System.out.print("请输入操作数1: ");
int num1 = sc.nextInt();
System.out.print("请输入操作数2: ");
int num2 = sc.nextInt();
System.out.print("请输入运算符: ");
String operator = sc.next();
String request = num1+";"+num2+";"+operator;
// 2. 构造请求,并发给服务器
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),0,request.getBytes().length,
InetAddress.getByName(serverIp),serverPort);
socket.send(requestPacket);
// 3. 从服务器中读取响应
DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
String response = new String(responsePacket.getData(),0,responsePacket.getLength());
// 4. 将结果显示到屏幕上
String log = String.format("req: %s; resp: %s",request,response);
System.out.println(log);
}
}
public static void main(String[] args) throws IOException {
CalcClient client = new CalcClient("127.0.0.1",9090);
client.start();
}
}
《新程序员》:云原生和全面数字化实践
50位技术专家共同创作,文字、视频、音频交互阅读
这与 Payubiz payment gateway sdk 关系不大一体化。但是,主要问题与构建项目有关。 每当我们尝试在模拟器上运行应用程序时。我们得到以下失败: What went wrong:
我有一个现有的应用程序,其中包含在同一主机上运行的 4 个 docker 容器。它们已使用 link 命令链接在一起。 然而,在 docker 升级后,link 行为已被弃用,并且似乎有所改变。我们现
在 Internet 模型中有四层:链路 -> 网络 -> 传输 -> 应用程序。 我真的不知道网络层和传输层之间的区别。当我读到: Transport layer: include congesti
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
前言: 生活中,我们在上网时,打开一个网页,就可以看到网址,如下: https😕/xhuahua.blog.csdn.net/ 访问网站使用的协议类型:https(基于 http 实现的,只不过在
网络 避免网络问题降低Hadoop和HBase性能的最重要因素可能是所使用的交换硬件,在项目范围的早期做出的决策可能会导致群集大小增加一倍或三倍(或更多)时出现重大问题。 需要考虑的重要事项:
网络 网络峰值 如果您看到定期的网络峰值,您可能需要检查compactionQueues以查看主要压缩是否正在发生。 有关管理压缩的更多信息,请参阅管理压缩部分的内容。 Loopback IP
Pure Data 有一个 loadbang 组件,它按照它说的做:当图形开始运行时发送一个 bang。 NoFlo 的 core/Kick 在其 IN 输入被击中之前不会发送其数据,并且您无法在 n
我有一台 Linux 构建机器,我也安装了 minikube。在 minikube 实例中,我安装了 artifactory,我将使用它来存储各种构建工件 我现在希望能够在我的开发机器上做一些工作(这
我想知道每个视频需要多少种不同的格式才能支持所有主要设备? 在我考虑的主要设备中:安卓手机 + iPhone + iPad . 对具有不同比特率的视频进行编码也是一种好习惯吗? 那里有太多相互矛盾的信
我有一个使用 firebase 的 Flutter Web 应用程序,我有两个 firebase 项目(dev 和 prod)。 我想为这个项目设置 Flavors(只是网络没有移动)。 在移动端,我
我正在读这篇文章Ars article关于密码安全,它提到有一些网站“在传输之前对密码进行哈希处理”? 现在,假设这不使用 SSL 连接 (HTTPS),a.这真的安全吗? b.如果是的话,你会如何在
我试图了解以下之间的关系: eth0在主机上;和 docker0桥;和 eth0每个容器上的接口(interface) 据我了解,Docker: 创建一个 docker0桥接,然后为其分配一个与主机上
我需要编写一个java程序,通过网络将对象发送到客户端程序。问题是一些需要发送的对象是不可序列化的。如何最好地解决这个问题? 最佳答案 发送在客户端重建对象所需的数据。 关于java - 不可序列化对
所以我最近关注了this有关用 Java 制作基本聊天室的教程。它使用多线程,是一个“面向连接”的服务器。我想知道如何使用相同的 Sockets 和 ServerSockets 来发送对象的 3d 位
我想制作一个系统,其中java客户端程序将图像发送到中央服务器。中央服务器保存它们并运行使用这些图像的网站。 我应该如何发送图像以及如何接收它们?我可以使用同一个网络服务器来接收和显示网站吗? 最佳答
我正在尝试设置我的 rails 4 应用程序,以便它发送电子邮件。有谁知道我为什么会得到: Net::SMTPAuthenticationError 534-5.7.9 Application-spe
我正在尝试编写一个简单的客户端-服务器程序,它将客户端计算机连接到服务器计算机。 到目前为止,我的代码在本地主机上运行良好,但是当我将客户端代码中的 IP 地址替换为服务器计算机的本地 IP 地址时,
我需要在服务器上并行启动多个端口,并且所有服务器套接字都应在 socket.accept() 上阻塞。 同一个线程需要启动客户端套接字(许多)来连接到特定的 ServerSocket。 这能实现吗?
我的工作执行了大约 10000 次以下任务: 1) HTTP 请求(1 秒) 2)数据转换(0.3秒) 3)数据库插入(0.7秒) 每次迭代的总时间约为 2 秒,分布如上所述。 我想做多任务处理,但我
我是一名优秀的程序员,十分优秀!