I'm working on TCP connection between two Windows10 laptops. I made the applications using Unity 2019.2.17f1. However, the TCP connection doesn't work. The Client application connects to the server only when I don't run the server application (this is strange though...), otherwise the client application shows the message "server is not found...".
I put the part of the codes here.
Client Program:
public class TCPClientManager : MonoBehaviour
{
// ip address(server) and port number
public string ipAddress = "192.0.0.1";
public int port = 3000;
private TcpClient m_tcpClient;
private NetworkStream m_networkStream;
private bool m_isConnection;
private string message;
void Start()
{
try
{
// connect to the server
m_tcpClient = new TcpClient(ipAddress, port);
m_networkStream = m_tcpClient.GetStream();
m_isConnection = true;
}
catch (SocketException)
{
m_isConnection = false;
// show a error message
// ...
}
}
void OnGUI()
{
if (m_isConnection)
{
GUILayout.Label("server is not found...");
return;
}
// some codes here
}
// some codes here
}
Server Program:
public class TCPServerManager : MonoBehaviour
{
// ip address(server) and port number
public string ipAddress = "192.0.0.1";
public int port = 3000;
private TcpListener m_tcpListener;
private TcpClient m_tcpClient;
private NetworkStream m_networkStream;
private bool m_isConnection;
private string message = string.Empty;
private void Awake()
{
Task.Run(() => OnProcess());
}
private void OnProcess()
{
var n_IpAddress = IPAddress.Parse(ipAddress);
m_tcpListener = new TcpListener(n_IpAddress, port);
m_tcpListener.Start();
m_tcpClient = m_tcpListener.AcceptTcpClient();
m_networkStream = m_tcpClient.GetStream();
while (true)
{
var buffer = new byte[256];
var count = m_networkStream.Read(buffer, 0, buffer.Length);
if (count == 0)
{
OnDestroy();
Task.Run(() => OnProcess());
break;
}
message += Encoding.UTF8.GetString(buffer, 0, count) + "\n";
}
}
// ....
}
Thank you very much for your comments in advice.
I think you inverted you m_isConnection variables values. You set it to true after connecting the server and false if not. But in OnGUI, if you found the connection then you print an error message and leave. Which means you do your //some code here only if no server was found.
Related
My application is running behind a corporate firewall and I need to use http proxy(http://theclientproxy.net:8080) to connect to internet
I have used the Netty client as below,
https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example/http/websocketx/client
Code:
public final class WebSocketClient {
static final String URL = System.getProperty("url", "wss://127.0.0.1:8080/websocket");
public static void main(String[] args) throws Exception {
URI uri = new URI(URL);
String scheme = uri.getScheme() == null? "ws" : uri.getScheme();
final String host = uri.getHost() == null? "127.0.0.1" : uri.getHost();
final int port;
final boolean ssl = "wss".equalsIgnoreCase(scheme);
final SslContext sslCtx;
if (ssl) {
sslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
EventLoopGroup group = new NioEventLoopGroup();
try {
final WebSocketClientHandler handler =
new WebSocketClientHandler(
WebSocketClientHandshakerFactory.newHandshaker(
uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders()));
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
#Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addFirst(new HttpProxyHandler(new InetSocketAddress("theclientproxy.net", 8080) ) );
p.addLast(sslCtx.newHandler(ch.alloc(), host, port));
}
p.addLast(
new HttpClientCodec(),
new HttpObjectAggregator(8192),
WebSocketClientCompressionHandler.INSTANCE,
handler);
}
});
Channel ch = b.connect(uri.getHost(), port).sync().channel();
handler.handshakeFuture().sync();
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String msg = console.readLine(); //THIS IS NULL IN DATA CENTER LOGS
if (msg == null) {
break;
} else if ("bye".equals(msg.toLowerCase())) {
ch.writeAndFlush(new CloseWebSocketFrame());
ch.closeFuture().sync();
break;
} else if ("ping".equals(msg.toLowerCase())) {
WebSocketFrame frame = new PingWebSocketFrame(Unpooled.wrappedBuffer(new byte[] { 8, 1, 8, 1 }));
ch.writeAndFlush(frame);
} else {
WebSocketFrame frame = new TextWebSocketFrame(msg);
ch.writeAndFlush(frame);
}
}
} finally {
group.shutdownGracefully();
}
Handler:
public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {
private final WebSocketClientHandshaker handshaker;
private ChannelPromise handshakeFuture;
public WebSocketClientHandler(WebSocketClientHandshaker handshaker) {
this.handshaker = handshaker;
}
public ChannelFuture handshakeFuture() {
return handshakeFuture;
}
#Override
public void handlerAdded(ChannelHandlerContext ctx) {
handshakeFuture = ctx.newPromise();
}
#Override
public void channelActive(ChannelHandlerContext ctx) {
handshaker.handshake(ctx.channel());
}
#Override
public void channelInactive(ChannelHandlerContext ctx) {
System.out.println("WebSocket Client disconnected!");
}
#Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
Channel ch = ctx.channel();
if (!handshaker.isHandshakeComplete()) {
try {
handshaker.finishHandshake(ch, (FullHttpResponse) msg);
System.out.println("WebSocket Client connected!");
handshakeFuture.setSuccess();
} catch (WebSocketHandshakeException e) {
System.out.println("WebSocket Client failed to connect");
handshakeFuture.setFailure(e);
}
return;
}
The application is able to connect to the websocket server endpoint from my local machine successfully.
But in the company datacenter where my application is deployed, I see the msg value is null and the websocket client is disconnected
Does that mean my connection is blocked at firewall? If that is the case then why did the statement "WebSocket Client connected!" is printed at all?
Thanks
The httpproxyhandler you used is correct
Just remove the BufferredReader code as mentioned below when deploying in linux, docker, etc:
Netty WebSocket Client Channel always gets inactive on Linux Server
I am new to spark streaming. I want to stream a url online in order to retrieve info from a certain URL, I used the JavaCustomReceiver in order to stream a url.
This is the code I'm using (source)
public class JavaCustomReceiver extends Receiver<String> {
private static final Pattern SPACE = Pattern.compile(" ");
public static void main(String[] args) throws Exception {
SparkConf sparkConf = new SparkConf().setAppName("JavaCustomReceiver");
JavaStreamingContext ssc = new JavaStreamingContext(sparkConf, new Duration(1000));
JavaReceiverInputDStream<String> lines = ssc.receiverStream(
new JavaCustomReceiver("http://stream.meetup.com/2/rsvps", 80));
JavaDStream<String> words = lines.flatMap(new
FlatMapFunction<String, String>() {
#Override
public Iterator<String> call(String x) {
return Arrays.asList(SPACE.split(x)).iterator();
}
});
JavaPairDStream<String, Integer> wordCounts = words.mapToPair(
new PairFunction<String, String, Integer>() {
#Override
public Tuple2<String, Integer> call(String s) {
return new Tuple2<>(s, 1);
}
}).reduceByKey(new Function2<Integer, Integer, Integer>() {
#Override
public Integer call(Integer i1, Integer i2) {
return i1 + i2;
}
});
wordCounts.print();
ssc.start();
ssc.awaitTermination();
}
String host = null;
int port = -1;
public JavaCustomReceiver(String host_, int port_) {
super(StorageLevel.MEMORY_AND_DISK_2());
host = host_;
port = port_;
}
public void onStart() {
new Thread() {
#Override
public void run() {
receive();
}
}.start();
}
public void onStop() {
}
private void receive() {
try {
Socket socket = null;
BufferedReader reader = null;
String userInput = null;
try {
// connect to the server
socket = new Socket(host, port);
reader = new BufferedReader(
new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
// Until stopped or connection broken continue reading
while (!isStopped() && (userInput = reader.readLine()) != null) {
System.out.println("Received data '" + userInput + "'");
store(userInput);
}
} finally {
Closeables.close(reader, /* swallowIOException = */ true);
Closeables.close(socket, /* swallowIOException = */ true);
}
restart("Trying to connect again");
} catch (ConnectException ce) {
// restart if could not connect to server
restart("Could not connect", ce);
} catch (Throwable t) {
restart("Error receiving data", t);
}
}
}
However, I keep getting a java.net.UnknownHostException
How can I fix this? What is wrong with the code that I'm using ?
After reading the code of the custom receiver referenced, it is clear that it is a TCP receiver that connects to a host:port and not an HTTP receiver that could take an URL. You'll have to change the code to read from an HTTP endpoint.
I am developing a cross platform app.
I need print in printer Intermec PR2
I use this codes:
Class in .Droid
[assembly: Xamarin.Forms.Dependency(typeof(clsBluetooth))]
namespace Bluetooth.Droid
{
public class clsBluetooth : IBluetooth
{
private BluetoothAdapter adapter = BluetoothAdapter.DefaultAdapter;
private BluetoothSocket socket = null;
private BufferedWriter outReader = null;
private BluetoothDevice device = null;
public void Imprimir(string pStrNomBluetooth, int intSleepTime, string pStrTextoImprimir)
{
try
{
string bt_printer = (from d in adapter.BondedDevices
where d.Name == pStrNomBluetooth
select d).FirstOrDefault().ToString();
device = adapter.GetRemoteDevice(bt_printer);
UUID applicationUUID = UUID.FromString("00001101-0000-1000-8000-00805f9b34fb");
socket = device.CreateRfcommSocketToServiceRecord(applicationUUID);
socket.Connect();
outReader = new BufferedWriter(new OutputStreamWriter(socket.InputStream));
outReader.WriteAsync(pStrTextoImprimir);
}
catch (Exception)
{
throw;
}
finally
{
}
}
public ObservableCollection<string> PairedDevices()
{
ObservableCollection<string> devices = new ObservableCollection<string>();
foreach (var bd in adapter.BondedDevices)
devices.Add(bd.Name);
return devices;
}
}
}
Interface in Potable
public interface IBluetooth
{
ObservableCollection<string> PairedDevices();
void Imprimir(string pStrNomBluetooth, int intSleepTime, string pStrTextoImprimir);
}
Call of method
DependencyService.Get<IBluetooth>().Imprimir(SelectedBthDevice,200,"HolaMundo");
My error happens when I enter the class in the .Droid and it executes the sentence socket.Connect (); Does not seem to connect to the device.
Someone could help me to see the script or how the code could change so that the connection to the device works correctly
Try creating the insecure socket communication like:
socket = device.CreateInsecureRfcommSocketToServiceRecord(applicationUUID);
instead of the existing secure one:
socket = device.CreateRfcommSocketToServiceRecord(applicationUUID);
If you are able to connect after that you can write to printer as follows:
byte[] buffer = Encoding.UTF8.GetBytes(pStrTextoImprimir);
socket.OutputStream.Write(buffer, 0, buffer.Length);
For further details refer to.
I am deploying a webapp, which internally queries elasticsearch. I am creating only one connection, and I want to close it when the webapp shuts down. I am using singleton pattern for creating the ES client and how do I destroy/close ES client? When the application shuts down, will the client get closed or I have to specify it/ where should I have the code to close the connection?
This is my code:
public class ESClientManager {
public static Client client = null;
private static Settings settings = null;
private static Object mutex = new Object();
private static final String CONFIG_CLUSTER_NAME = "cluster.name";
private static final String CLUSTER_NAME = "qatool_es";
private static final String[] transportAddress = {
"127.0.0.1"
};
private static final int transportPort = 9300;
private ESClientManager() {
}
public static Client getClient() {
if (client == null) {
synchronized (mutex) {
settings = ImmutableSettings.settingsBuilder()
.put(CONFIG_CLUSTER_NAME, CLUSTER_NAME).build();
client = new TransportClient(settings);
for (int i = 0; i < transportAddress.length - 1; i++) {
((TransportClient) client).addTransportAddress(new InetSocketTransportAddress(transportAddress[i], transportPort));
}
logger.info("Elastic search client initialized");
}
}
logger.info("Returning the existing client");
return client;
}
}
The sample java code does show a call to client.close();
Call this when your app closes, or look into hooks to force it to be run.
I'm writing a Metro app in Windows 8 Consumer Preview.
However, I'm unable to use the TcpClient in .NET 4.5, there doesn't seem to be a place to add the assembly reference.
http://msdn.microsoft.com/en-us/library/1612451t(v=vs.110).aspx
TcpClient is not supported on the metro side. You can use StreamSocket class instead. Here is a sample on how to use it to create a TCP Socket, make a connection, send and receive data. The samples are in JS and C++ but the same class will work for C#.
Ultimately, we should probably use the new Metro NET stuff. However, if porting a lot of code and depending on how much of the TcpClient members you are using, it might not be so bad to just create a limited implementation around the Metro objects. I wanted to do a quick port of a bunch of code over to Metro in a hurry (just to try out some stuff), so I slapped together something that seemed to work, but most certainly not ideal. (You end up doing some sync-ing of async methods which is commonly frowned upon.)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
namespace MetroNetHelper
{
public class IPAddress // assumes IPv4 currently
{
public string IP_String;
public IPAddress() { }
public IPAddress(string IP) { IP_String = IP; }
public static IPAddress Broadcast { get { return new IPAddress("255.255.255.255"); } }
public static IPAddress Parse(string IP) { return new IPAddress(IP); }
public static bool TryParse(string V, out IPAddress Addr)
{
try
{
Addr = IPAddress.Parse(V);
return true;
}
catch { Addr = null; return false; }
}
public HostName GetHostNameObject() { return new HostName(IP_String); }
public byte[] GetAddressBytes()
{
string[] Fields = IP_String.Split('.');
byte[] temp = new byte[4];
for (int i = 0; i < temp.Length; i++) temp[i] = byte.Parse(Fields[i]);
return temp;
}
}
public class IPEndPoint
{
public IPAddress Address;
public int Port;
public IPEndPoint() { }
public IPEndPoint(IPAddress Addr, int PortNum)
{
Address = Addr; Port = PortNum;
}
}
public class NetworkStream
{
private DataReader Reader;
private DataWriter Writer;
public void Set(StreamSocket HostClient)
{
Reader = new DataReader(HostClient.InputStream);
Reader.InputStreamOptions = InputStreamOptions.Partial;
Writer = new DataWriter(HostClient.OutputStream);
}
public int Write(byte[] Buffer, int Offset, int Len)
{
if (Offset != 0 || Len != Buffer.Length) throw new ArgumentException("Can only write whole byte array");
Writer.WriteBytes(Buffer);
Task Tk = Writer.StoreAsync().AsTask();
Tk.Wait();
return Buffer.Length;
}
public int Read(byte[] Buffer, int Offset, int Len)
{
if (Offset != 0 || Len != Buffer.Length) throw new ArgumentException("Can only read whole byte array");
Task<uint> Tk = Reader.LoadAsync((uint)Len).AsTask<uint>();
Tk.Wait();
uint Count = Tk.Result;
for (int i=0;i<Count;i++)
{
Buffer[i] = Reader.ReadByte();
}
return (int)Count;
}
public bool DataAvailable
{
get
{
return true; // Read() will still work if no data; could we do read ahead 1 byte to determine?
}
}
}
public class TcpClient
{
private StreamSocket sock;
public void Connect(IPEndPoint EndPt)
{
try
{
sock = new StreamSocket();
HostName Hst = EndPt.Address.GetHostNameObject();
Task Tsk = sock.ConnectAsync(Hst, EndPt.Port.ToString()).AsTask();
Tsk.Wait();
}
catch (Exception ex) { MetroHelpers.UnpeelAggregate(ex); }
}
public void Close()
{
sock.Dispose();
sock = null;
}
public NetworkStream GetStream()
{
var N = new NetworkStream();
N.Set(sock);
return N;
}
}
public static class MetroHelpers
{
public static void UnpeelAggregate(Exception Ex)
{
AggregateException Ag_Ex = Ex as AggregateException;
if (Ag_Ex == null) throw Ex;
if (Ag_Ex.InnerExceptions.Count > 0)
{
if (Ag_Ex.InnerExceptions.Count == 1) throw Ag_Ex.InnerExceptions[0];
StringBuilder Str = new StringBuilder();
foreach (Exception X in Ag_Ex.InnerExceptions)
{
Str.AppendLine(X.Message);
}
throw new Exception(Str.ToString(), Ag_Ex);
}
else throw Ag_Ex;
}
}
} // END NAMESPACE
This was just something I did quick and dirty in a morning. If it helps anyone with ideas, great. Again, we are most likely better off developing the way Microsoft wants us for Metro apps. It just gets frustrating when they keep changing the ruddy framework. (If Xamarin can keep consistent frameworks on iOS/Android/etc, why can't MS on their own OS's!)