我研究了android蓝牙的例子.
令我感到困惑的是,其他设备已发送连接请求,并且如果以前的连接存在,服务器只是被阻止了很长时间而没有被接受.
是否有可能执行服务器套接字并接受许多连接而不仅仅是一个连接的Android设备?是否有任何原因可能导致被accept()阻止的服务器,例如,错误的UUID或类似的东西?
我做的操作如下,
因为第一个连接成功,我不会在第二个连接上更改UUID.所以我认为UUID不是关键.建立第一个连接后,服务器套接字将等待另一个连接.可悲的是,它只是等待和阻止,不接受作为第一个连接.
public void run() {
if (D) Log.d(TAG, "BEGIN ServerSocketThread" + this);
BluetoothSocket socket = null;
while(true) {
try {
Log.i(TAG, "[ServerSocketThread] Enter while loop");
socket = mmServerSocket.accept();
Log.i(TAG, "[ServerSocketThread] Got client socket");
} catch (IOException e) {
Log.e(TAG, "accept() failed", e);
break;
}
if (socket!=null) {
synchronized (BluetoothConnService.this) {
Log.i(TAG, "[ServerSocketThread] "+socket.getRemoteDevice()+" is connected.");
ConnectedThread tmpThread = new ConnectedThread(socket);
tmpThread.start();
break;
}
}
}
BluetoothConnService.this.startSession();
}
Run Code Online (Sandbox Code Playgroud)
它是服务器套接字线程的一部分.每当我想进行第二次连接时,logcat显示它将在日志" [ServerSocketThread] …
我被一位教授挑战在Android上开发一个小型蓝牙演示应用程序.直到两周前,当他给我这个挑战时,我对Android的开发一无所知.我对Java编程也很陌生,所以我从远处开始.但无论如何...
所以我做了大部分的教程,我读到了Android中的蓝牙,查看了蓝牙聊天示例代码,我现在正在尝试做我的小应用程序.因此,对于我的演示,我将尝试在我的真实手机和蓝牙鼠标之间建立连接.我想在我的手机屏幕上移动一个形状以响应我的鼠标移动.
我遇到很多问题,但到目前为止我的主要问题是用不安全的鼠标打开一个插座.当我尝试使用该方法时listenUsingRfcommWithServiceRecord,它会将UUID作为参数.但是我的鼠标很可能没有UUID来响应,所以我猜这种方法并不好.
当我阅读有关此方法的文档时,它说要使用像鼠标这样的设备打开不安全的服务器套接字,我必须使用该listenUsingInsecureRfcommWithServiceRecord方法.但是当我调用它时,这个方法是不可用的,它以红色加下划线,而Eclipse表示它对于BluetoothAdapter类型是未定义的.
private BluetoothServerSocket connectDevice(BluetoothAdapter adapter, BluetoothDevice device){
BluetoothServerSocket socket = null;
try{
socket = adapter.listenUsingInsecureRfcommWithServiceRecord(device.getName(), UUID.randomUUID());
}
catch(IOException e){
Toast.makeText(this, "Connection failed.\n" + e.getMessage(), Toast.LENGTH_SHORT);
}
return socket;
}
Run Code Online (Sandbox Code Playgroud)
如果我做错了,请不要激怒我,这是我的第一个问题,我开始使用Java编程.
该getaddrinfo()函数不仅允许客户端程序有效地找到用于创建给定主机的套接字的正确数据,它还允许服务器绑定到正确的套接字 - 理论上.
我刚刚了解了这一点并开始通过Python来解决它:
from socket import *
for i in getaddrinfo(None, 22, AF_UNSPEC, SOCK_STREAM, IPPROTO_IP, AI_PASSIVE): i
Run Code Online (Sandbox Code Playgroud)
产量
(2, 1, 6, '', ('0.0.0.0', 22))
(10, 1, 6, '', ('::', 22, 0, 0))
Run Code Online (Sandbox Code Playgroud)
是什么让我想知道是否有什么不对劲.
我应该对这些答案究竟做些什么?我是不是该
listen()所有这些答案的插座,或者我应该该联机帮助页中的示例建议我只选择第一个并且如果它没有错误就对它感到满意,但在我的示例中我只通过IPv4获得连接.
但是,如果我尝试所有这些,我不得不担心2个服务器套接字,这是不必要的,因为如果满足某些条件(OS,套接字标志等),IPv6服务器套接字也会监听IPv4.
我错在哪里?
编辑:很明显,我没想错,但我的电脑做错了.我使用/etc/gai.confOpenSUSE附带的默认值.如果有人能指出我正确的方向,那将是很好的.
编辑2:在给定的情况下,strace在读取后给出内部进行的以下调用/etc/gai.conf(现在使用端口54321,因为我认为使用端口22可能会产生一些不良影响,但事实并非如此):
socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET6, sin6_port=htons(54321), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
getsockname(3, {sa_family=AF_INET6, sin6_port=htons(38289), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, …Run Code Online (Sandbox Code Playgroud) 我设法创建了一个C#Server,它使用发送文件到AS3(AIR)客户端sockets.在AS3方面,我正在使用该flash.net.Socket库来接收数据TCP.
这是它的工作原理:
- >我打开我的服务器,它监听客户端(我可以创建一个连接设备列表);
- >我打开我的客户端,它会自动接收数据;
接收数据的触发事件是在客户端上进行的,即我只是打开服务器,当客户端打开时,它获取数据,触发这些事件:
socket.addEventListener(Event.CONNECT, onConnect); -> to connect to the server
socket.addEventListener(Event.SOCKET_DATA, onDataArrival); -> to receive the data
Run Code Online (Sandbox Code Playgroud)
现在我想做一些不同的事情.我不想在客户端上触发它,我希望服务器这样做,即,我想打开我的客户端,并在服务器上放入客户端将获取数据.
那么为什么我要尝试让客户端成为客户端/服务器呢?好吧,因为我的服务器是一台机器,而我的客户端是连接服务器的XXX移动设备,这是我实现这一目标的方法.
所以,鉴于我刚才所说的,我设法创建了我的AS3客户端/服务器应用程序,使用该flash.net.ServerSocket库就像我想要的那样.
首先我把客户端听了:
serverSocket.bind(portNumber, "10.1.1.212");
serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, onConnectServer);
serverSocket.listen();
Run Code Online (Sandbox Code Playgroud)
然后我使用了接收数据 flash.net.Socket Event.SOCKET_DATA
这就是它.像我想要的那样工作.
但是,它flash.net.ServerSocket与移动设备不兼容,但......
所以这是我的问题:我需要从C#服务器发送文件(需要监听客户端以便我可以创建连接设备列表)到AS3(AIR)客户端,但我必须定义哪个客户端正在获取数据服务器,客户端需要随时准备接收数据,因此,听,但有很多,这就是我认为它们作为客户端的原因.
我的问题是:有没有办法让客户端监听传入的连接并在事件发生时触发事件,而不使用AS3中的服务器套接字?
此外,如果您有不同的方法来实现我的目标,而不使用C#服务器< - > AS3客户端/服务器逻辑,请随时提出您的意见.
我正在创建一个基于 Java 的服务器。
我正在使用服务器套接字来接受传入消息。
然而,在我的程序中的某个时刻,我希望服务器套接字侦听另一个端口。
我关闭服务器套接字。并用我的新端口开始一个新的端口。一切安好。
但是,当我再次将服务器套接字更改为以前的端口时,会出现错误。
我读过一些内容,服务器套接字在关闭后仍处于超时状态一段时间。
所以这是我的问题:我可以绕过服务器套接字的这种超时状态,并在关闭端口并想要再次侦听同一端口后使端口再次可用吗?
编辑:我的函数用于创建和监听服务器套接字,我的函数用于使服务器套接字无效并在之后立即创建一个新的套接字
public void makeServerSocketWithPort(int portnr) throws IOException, Exception
{
server = new ServerSocket(portnr);
server.setReuseAddress(true);
while(!portchanged)
{
Socket sock = server.accept();
System.out.println(server.getLocalPort());
System.out.println(sock.getLocalPort());
handler = new Requesthandler(sock); //should be in a thread
System.out.println(server.getLocalPort());
System.out.println(sock.getLocalPort());
}
}
public void invalidateRequestHandler(int newPort)
{
if(server != null)
{
portchanged = true;
try {
server.close();
} catch (IOException ex) {
Logger.getLogger(Controlserver.class.getName()).log(Level.SEVERE, null, ex);
}
}
portchanged = false;
makeServerSocketWithPort(newPort);
}
Run Code Online (Sandbox Code Playgroud)
错误堆栈跟踪:
Exception in thread "main" java.net.SocketException: …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个只启动蓝牙的服务器程序,创建服务器套接字,等待某些设备连接并接受连接.
onClick()方法启动蓝牙,然后我调用AcceptThread()方法创建一个服务器套接字并开始监听.然后调用run()接受连接.
但它没有用.我的应用程序停止了.知道为什么吗?
代码如下:
public class MainActivity extends Activity {
public BluetoothAdapter mBluetoothAdapter;
private BluetoothServerSocket mmServerSocket;
private static final UUID MY_UUID_SECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text=(TextView)findViewById(R.id.textView1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.button1:
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
text.setText("Does not support bluetooth");
return;
}
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
text.setText("Discoverable!!");
AcceptThread(); …Run Code Online (Sandbox Code Playgroud) 在这里,我正在开发一个具有Java套接字的项目,并且在服务器和客户端之间实现正确的时间同步方面存在问题。我将用一个简单的例子来描述问题:
服务器在GMT上运行,并保留包含各种项目的数据库。这些商品中有一些是特价商品,但是这些商品在到期前有时间限制。
因此,假设服务器时间现在是9:00 AM(GMT),并且有一个商品要在10:00 AM(GMT)结束。
客户端可能与服务器位于不同的时间和时区。因此,假设客户时间现在是8:00 AM(GMT-1),我可以花时间将其调整为客户的时区,发现它在9:00 AM(GMT-1)结束,即1个小时。
问题:当用户设置了自定义时间时,如何计算剩余时间。
例如,上述客户端将时钟手动设置为提前半小时,即8:30 AM(GMT-1)。如果您只是进行时区转换,则该商品仍将在9:00(GMT-1)结束,因此,要约完成的剩余时间是错误的(30分钟)。
可能有人说,一种可能的解决方案是将客户端设置为从服务器询问以秒为单位的剩余时间,而不是确切的日期结束。但是我想在客户端实现类似倒数秒的功能。(如果报价在60秒内结束,则界面将变为60,59,58,..,1,0)。因此,每秒向服务器发送一个请求以获取剩余时间并不是有效的网络。
让我担心的另一件事是,如果您确实要求“以秒为单位的剩余时间”,那么在慢速的网络上,服务器的响应将不会立即到来,因此在客户端收到结果之前,时间已经到了。
我一直致力于用 Java 编写 Web Socket 服务器,这一点让我困惑了一段时间。在 GitHub 上,有 TooTallNate 开发的这个库,它是“100% Java 中的准系统 WebSocket 客户端和服务器实现”: https: //github.com/TooTallNate/Java-WebSocket
它拥有大量明星,并且正在积极开发中。
但似乎 Java 的主库中已经有了 websocket 功能?https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_Java
还有 Jetty 的 WebSocket 之类的东西:http://www.eclipse.org/jetty/documentation/9.4.x/jetty-websocket-server-api.html
还有 Netty,它似乎也有 WebSocket 的东西。
那么它们之间到底有什么区别呢?这是简单性的问题吗?还是性能?或者它们是完全不同的东西?如果我需要低延迟高频发送 5-10 kb 消息,是否有一种最合适的选项?
我已经设置了一个服务器,它通过下面提到的 java 函数侦听加密的字节数组。早些时候,我使用 java (android) 来构建我的应用程序,因此使用相同的 java 函数很容易,但我无法弄清楚该函数的 dart 等效项(flutter)是什么,该函数接受字符串作为输入并返回 AES 加密字节数组作为输出,我可以将其写入 TCP 套接字。
另外,我非常感谢您帮助了解如何将生成的字节数组写入服务器,然后读取类似的响应并通过 dart (颤振)对其进行解密
我已经成功地编写了简单的字符串并通过 dart 接收简单的字符串作为 tcp 服务器的输入和输出,但无法对加密的字节数组执行相同的操作。在java中,我使用DataOutputStream将响应发送到服务器,如下所示
DataOutputStream dOut = newDataOutputStream(socket.getOutputStream());
byte[] s2 = Encrypt3.encrypt2(myString);
dOut.writeInt(s2.length); // write length of the message
dOut.write(s2);
Run Code Online (Sandbox Code Playgroud)
这是我用于aes加密的java函数
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Encrypt3 {
public static String key = "mykey";
public static byte[] encrypt2(String text ){
String encrypt ="";
try{
// Create key and cipher
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES"); …Run Code Online (Sandbox Code Playgroud) 我想查看我的项目的日志
脚步 :
我克隆了一个套接字应用程序。然后我运行npm install pm2 -g安装 pm2
我跑pm2 start
有用。它显示我的套接字应用程序的表格
但是如果我运行pm2 logs查看日志,则存在如下错误:
1|mycompany | C:\PROGRAM FILES\NODEJS\NPM.CMD:1
1|mycompany | (function (exports, require, module, __filename, __dirname) { :: Created by npm, please don't edit manually.
1|mycompany | ^
1|mycompany |
1|mycompany | SyntaxError: Unexpected token :
1|mycompany | at new Script (vm.js:79:7)
1|mycompany | at createScript (vm.js:251:10)
1|mycompany | at Object.runInThisContext (vm.js:303:10)
1|mycompany | at Module._compile (internal/modules/cjs/loader.js:657:28)
1|mycompany | at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
1|mycompany | at Module.load …Run Code Online (Sandbox Code Playgroud)