I am trying to connect two Android devices to a c#-server and I always get a connection timeout.
The java-code is simple:
Socket socket = new Socket(mAddress, PORT);
If I start a java-server on the pc then the connection is successful. So its not a network/firewall problem.
But my c#-server just won't accept any connections, code:
private TcpListener serverSocket;
private TcpClient clientSocket1;
private TcpClient clientSocket2;
private void Form1_Load(object sender, EventArgs e)
{
serverSocket = new TcpListener(IPAddress.Any, port);
clientSocket1 = default(TcpClient);
clientSocket2 = default(TcpClient);
serverSocket.Start();
clientListenerThread = new Thread(wait4Clients);
clientListenerThread.Start();
}
private void wait4Clients()
{
logToConsole("Clientlistener started");
clientSocket1 = serverSocket.AcceptTcpClient();
logToConsole("Client No 1 started!");
clientSocket2 = serverSocket.AcceptTcpClient();
logToConsole("Client No 2 started!");
}
I also tried System.Net.Sockets.Socket instead of System.Net.Sockets.TcpClient, didnt worked either.
Thanks a lot
EDIT: Seems the code is perfectly fine. If I run the exe and not debug mode via Visual Studio, everything works. So the debug mode somehow prevents the server socket from working correctly. Any ideas why this happens?
// TCP Server C#, look at [msdn][1]
try
{
// Set the TcpListener on port 8080 of Any IP Address.
TcpListener server = new TcpListener(IPAddress.Any, 8080);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[1024];
String data = null;
// Enter the listening loop.
while(true) {
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
data = null;
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while((i = stream.Read(bytes, 0, bytes.Length))!=0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
}
Related
I am trying to implement a web socket server in java. The code for the server is :-
ServerSocket serverSocket = new ServerSocket();
SocketAddress socketAddress = new InetSocketAddress(9000);
LOGGER.info("Listening on port :: 9000");
serverSocket.bind(socketAddress,5 );
while (true) {
Socket socket = serverSocket.accept();
Processor processor = Processor.getInstance(processorCounter++);
try {
processor.begin(socket);
} catch (AppException e) {
LOGGER.info(e.getMessage(), e);
}
}
I am creating a new thread Processor which accepts the socket and begins to publish response on it without closing the connection. The connection is long-term and persistent.
When I hit this server with around 2000 requests, I observe that no more than 249 threads are getting created. The question is that why no more than 249 threads/processors are being spawned?
PS.:
requests are being sent from Google Chrome
Javascript that makes the request -
const func1=function(){
for(var i=1;i<=2000;i++){
var ws=new WebSocket("ws://localhost:9000");
ws.onopen=function(event){
ws.send("are you a teapot?! from client "+i);
};
ws.onmessage=function(event){
console.log("Server says : "+event.data);
};
ws.onerror=function(event){
console.log("error () -> "+JSON.stringify(event));
};
ws.onclose=function(event){
console.log("close () -> "+JSON.stringify(event));
};}
}
Android especially.
I will try to establish a connection between two devices (android - android) where one will create a server socket, connect the other device to the client, close the socket, and the connection between the two devices remains. So simple.
Server
#Override
public void onResume() {
super.onResume();
//// !!! only for test !!!
(new Thread(new Runnable() {
#Override
public void run() {
try {
int port = 33000;
SocketAddress allInterfaces = new InetSocketAddress("0.0.0.0", port);
ServerSocketChannel channel = MuxServerSocketChannelFactory
.openAndBindServerSocketChannel(null, allInterfaces, 3);
ServerSocket server = channel.socket();
Socket socket = server.accept();
Log.i("test", "host was connected!!!: " + socket.getInetAddress().getHostAddress());
callback.onConnected(socket);
server.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
})).start();
if (true) return;
//// !!! end test on real device !!!
}
Client
int privateServerPort = 33000;
int publicServerPort = 25000;
InetAddress privateServerIpAddr = InetAddress.getByName("172.23.9.120");
InetAddress publicServerIpAddr = InetAddress.getByName("xx.xx.xx.xx"); // correct IP address
Socket socket = new Socket(publicServerIpAddr, publicServerPort,
privateServerIpAddr, privateServerPort);
// never connected
The problem arises when these devices are not in one LAN or in one, but via a VPN. It is not possible to create this connection at this time.
I've been looking for a long time here (Stackoverflow), but it does not work for me. Some of the Libraries I tried:
Portmapper
// Discover port forwarding devices and take the first one found
List<PortMapper> mappers = PortMapperFactory.discover(networkBus, processBus);
PortMapper mapper = mappers.get(0);
// mappers always return null
Cling
final PortMapping desMapp = new PortMapping(
33000,
Tool.getLocalHost(false).getHostAddress(),
PortMapping.Protocol.TCP
);
UpnpService service = new UpnpServiceImpl(new AndroidUpnpServiceConfiguration());
RegistryListener registryListener = new PortMappingListener(desMapp) {
#Override
public synchronized void deviceAdded(Registry registry, Device device) {
super.deviceAdded(registry, device);
// this callback is never call
}
};
service.getRegistry().addListener(registryListener);
Collection<Device> all = service.getControlPoint().getRegistry().getDevices();
// the value all has 0 size
service.getControlPoint().search();
Thread.sleep(5000); // anything value
all = service.getControlPoint().getRegistry().getDevices();
// again the size is 0
Is there a really simple example of How the server and client should look?
All IP addresses and ports i know. I'm testing it on Huawei P9 Lite, Elephone P9000.
I do not work with UPnP, NAT and so on.
Thank you very much for your help.
I am trying to create a socket connection between a .Net server application and Java Client Application.
I am getting an error from the java client application:
Connection refused: connect
Notes:
Communicating with a .Net Client Application, works fine.
I have disables the windows firewall
Undoubtedly, I am running the server application in the background and then I am running the client application
Following are my server code (C#):
public class Server
{
public Server()
{
CreateListener();
}
public void CreateListener()
{
// Create an instance of the TcpListener class.
TcpListener tcpListener = null;
IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
string output;
try
{
// Set the listener on the local IP address
// and specify the port.
tcpListener = new TcpListener(ipAddress, 13);
tcpListener.Start();
output = "Waiting for a connection...";
}
catch (Exception e)
{
output = "Error: " + e.ToString();
MessageBox.Show(output);
}
}
}
and client application code (Java):
public class smtpClient {
public void Send() {
Socket smtpSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
try {
smtpSocket = new Socket("localhost", 13); // FAILURE
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
It fails at the following line in the Java Client Application:
smtpSocket = new Socket("localhost", 13);
I can't tell what is the issue you are facing, but you need to start with a solid foundation to discover these issues.
As a rule of thumb, you should always write one piece (typically the server) first and verify connectivity (say using telnet) and then write the other piece (typically client) and verify its connectivity.
I always keep a Standard Client and Server handy to test whether its my code or its the environment/configuration.
Below is a sample code that works fine to test connectivity.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class ClientServer {
static void Main() {
new Thread(() => { StartServer("localhost", 5013); }).Start();
Thread.Sleep(100);
Console.WriteLine("\nPress enter to start the client...");
Console.ReadLine();
StartClient("localhost", 5013);
}
public static void StartServer(string serverInterface, int port) {
try {
IPHostEntry hostInfo = Dns.GetHostEntry(serverInterface);
string hostName = hostInfo.HostName;
IPAddress ipAddress = hostInfo.AddressList[0];
var server = new TcpListener(ipAddress, port);
server.Start();
Console.WriteLine($"Waiting for a connection at {server.LocalEndpoint}");
Console.WriteLine("Press ctrl+c to exit server...");
while (true) {
TcpClient client = server.AcceptTcpClient();
Console.WriteLine($"Server says - Client connected: {client.Client.RemoteEndPoint}");
ThreadPool.QueueUserWorkItem((state) => {
using (var _client = (TcpClient)state)
using (NetworkStream stream = _client.GetStream()) {
string msg = stream.ReadAsciiData();
if (msg == "Hello!") {
stream.WriteAsciiData($"Time:{DateTime.Now: yyyy/MM/dd HH:mm zzz}. Server name is {hostName}");
}
}
}, client);
}
} catch (Exception e) {
Console.WriteLine(e);
}
}
public static void StartClient(string serverInterface, int port) {
Console.WriteLine("Client started...");
try {
using (var client = new TcpClient(serverInterface, port))
using (NetworkStream stream = client.GetStream()) {
Console.WriteLine("Client says - Hello!");
stream.Write(Encoding.ASCII.GetBytes("Hello!"));
string msg = stream.ReadAsciiData();
Console.WriteLine($"Client says - Message from server: Server#{client.Client.RemoteEndPoint}: {msg}");
}
} catch (Exception e) {
Console.WriteLine(e);
}
Console.WriteLine("Client exited");
}
}
static class Utils {
public static void WriteAsciiData(this NetworkStream stream, string data) {
stream.Write(Encoding.ASCII.GetBytes(data));
}
public static string ReadAsciiData(this NetworkStream stream) {
var buffer = new byte[1024];
int read = stream.Read(buffer, 0, buffer.Length);
return Encoding.ASCII.GetString(buffer, 0, read);
}
public static void Write(this NetworkStream stream, byte[] data) {
stream.Write(data, 0, data.Length);
}
}
Now to your specific problem,
The choice of port 13, is not ideal for testing. Usually all ports below 1024 are considered privileged. i.e. a firewall or antivirus might block your attempt to listen on that port
Remember that IPV6 addresses plays a role. Your machine might have that enabled or disabled based on your configuration. You want to make sure that if your server is listening on a IPv6 interface, then your client also connects on the same
Which brings us to another related point: Irrespective of you are using IPv6 interface or not, the client needs to connect to the same interface the server is listening on. This might seem obvious, but is often missed. A typical machine
has at-least 2 interfaces: One for localhost (127...* called loopback interface) and another non local (typically 10...* or 192...*, but not restricted to it). It can so happen (especially when you pick the first available interface to bind your server without knowing which one it is) that server might be listening on non loopback interface like say 192.168.1.10 interface and the client might be connecting to 127.0.0.1, and you can see why the client will get "connection refused" errors
The sample code above works and you can test your code with it. You can us telnet for a client or just my sample code. You can play around changing the serverInterface values to some surprising discoveries which are accentuated by
ipAddress = hostInfo.AddressList[0] line
Hope this helps you with your debugging
I have searched everywhere to find an answer for this question:
I have a TCP client on my android application that sends an message to the server which is written in Visual Basic .NET Framework 4.
Now i want to send an message from my server to the phone over 3g, it works on wifi and 3g..
private class startserver extends Thread
{
public void server() throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(8765);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println(clientSentence.substring(1));
msgshower = clientSentence.substring(1);
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "Received: " + msgshower , Toast.LENGTH_LONG).show();
}
});
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
#Override
public void run() {
try {
server();
} catch (Exception e) {
e.printStackTrace();
}
}
I start it in the OnCreate method
Now i send a message with (VB.NET)
Private Sub sends(ByVal message As String)
Dim tcp As New TcpClient
tcp.Connect(connectedIP, 8765)
Dim bw As New IO.BinaryWriter(tcp.GetStream)
bw.Write(message)
bw.Close()
tcp.Close()
End Sub
On wifi it will arrive, on 3g it wont... any idea's how to do this?
How do other applications archive this?
I think you're having problem with the ip address asigned by your mobile phone operator. The fact that works on wifi, but not on 3G, I think that is because your mobile(when connected through 3G) doesn't have a public IP address.
When you use SocketServer in your mobile, you're opening a port a waiting for others to connect to it. If your IP address is not reachable from internet, it won't happen (it's like having a computer behind a firewall.)
Could you try to implement the server in the VB machine, assuming that it has a public reachable address? This way, the phone wouldn't act as a server, it wouldn't be necessary to have a reachable address, as long as the VB machine has one. Then, you should use Socket class to bind to the server ip and port.
Totally confused by your code list above..
If you want to host a server in VB.NET, you should not use TcpClient class but TcpListener and if you need a better performance, use Socket class directly.
At the Android client side, you should new Socket(server,servPort), when you want to send message, write the outputStream, and read the inputStream to receive message.
I'm currently using a Java implementation of the Reliable UDP protocol, found here. The project has absolutely no tutorials so I have found it really hard to identify problems.
I have set up a client and server. The server runs on localhost:1234 and the client runs on localhost:1235. The server is first established, and loops listening for connections -
try {
ReliableSocket clientSocket = server.socket.accept();
InetSocketAddress clientAddress = (InetSocketAddress) clientSocket.getRemoteSocketAddress();
Logger.getLogger("ServerConnectionListener").info("New Connection from "+
clientAddress.getHostName()+":"+clientAddress.getPort()+" Processing...");
LessurConnectedClient client = new LessurConnectedClient(clientSocket);
ClientCommunicationSocketListener listener = new ClientCommunicationSocketListener(this, client);
clientSocket.addListener(listener);
} catch (Exception e) {
e.printStackTrace();
}
When a connection is established, it creates a listener for events on that socket -
class ClientCommunicationSocketListener implements ReliableSocketListener {
ServerConnectionListener connectionListener;
LessurConnectedClient client;
public ClientCommunicationSocketListener(ServerConnectionListener connectionListener, LessurConnectedClient client){
this.connectionListener = connectionListener;
this.client = client;
}
#Override
public void packetReceivedInOrder() {
connectionListener.server.handlePacket(client);
}
#Override
public void packetReceivedOutOfOrder() {
connectionListener.server.handlePacket(client);
}
}
When a packet is received, it passes it to server.handlePacket, which performs a debug routine of printing "Packet Received!".
My client connects to the server as so -
LessurClient client = new LessurClient();
InetSocketAddress a = (InetSocketAddress) server.getSocket().getLocalSocketAddress();
Logger.getLogger("client-connector").info("Trying to connect to server "+
a.getAddress().toString()+":"+
a.getPort());
client.connect(a.getAddress(), a.getPort());
// LessurClient.connect
public void connect(InetAddress address, int port){
try {
socket = new ReliableSocket(address, port, InetAddress.getLocalHost(), 1235);
isConnected = true;
Logger.getLogger("LessurClient").info("Connected to server "+address.getHostAddress()+":"+port);
} catch (IOException e) {
e.printStackTrace();
}
}
I have linked my code so when I press the key 'Z', it will send a packet to the server as so -
public void sendPacket(GamePacket packet){
if(!isConnected){
Logger.getLogger("LessurClient").severe("Can't send packet. Client is not connected to any server.");
return;
}
try {
OutputStream o = socket.getOutputStream();
o.write(packet.getData());
o.flush();
Logger.getLogger("LessurClient").info("Sending Packet with data \""+packet.getData()+"\" to server "+socket.getInetAddress().toString()+":"+socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
My problem is, after sending 32 packets, the server no longer receives packets, and after sending 64 packets, it crashes. I have investigated into the code, and it appears that its something associated with packets not being removed from the receive queue, as when I changed the _recvQueueSize variable in ReliableSocket.java:1815 from 32 to 40, I could now send 40 packets without something going wrong.
Could someone help me identify this issue? I've been looking at the code all day.
I managed to fix the problem.
You see, since this is an implementation of RUDP, it extends most of the Socket classes. Specifically, ReliableSocket.getInputStream(), was custom coded to a managed input stream. My problem was, I was receiving the packets, but not reading from the buffer.
When you receive a packet you're supposed to read from the buffer, otherwise the packet will not be dropped from the queue.
So all I had to do, was everytime I received a packet, read the size of the packet, and continue.