In node.js I'd like to create a client that:
open a socket to "server1"
through this socket: send info (array of bytes) to "server1" (this will activate a module on server side that will send data to client on irregular basis)
read data sent by "server1"
Can I only use a socket that is created when my client startup and then wait for data from server1 or do I need to implement a server instead ?
var net = require("net");
var client = net.createConnection(port, host);
client.on("connect", sendInfo);
client.on("data", readData);
client.on("end", cleanUp);
Just create a TCP connection to your server. Then just do stuff with it.
Related
We have a situation where client writes faster than the server can read, say every 1 second or less a client writes to a server making the tcp socket buffer full and therefore disconnects.
How to handle this sort of situation?
Is there a way to check tcp socket buffer from client side before writing and waits until buffer is freed and can send again?
Here is a sample pseudo code to easily reproduce the issue
Server
socket = create server Socket at port 7777;
socket->Accept(); //wait for just 1 connection
while(true)
{
// just do nothing and let the client fill the buffe
}
Client
socket = connect to localhost 7777
while(true)
{
socket->write("hello from test");
}
this will loop until write buffer is full, and it will hang up, and will disconnects with win socket error 10057.
I have this binding socket:
Socket mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
mainSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0));
And I need to know when an extern client is connected and disconnected from my servicies( ftp, database server, app server, etc).
thank for advance.
What I have tried:
I tried with these methods but, did not work for me.
mainSocket.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0), new AsyncCallback(ClientConnected), null);
mainSocket.BeginDisconnect(true, new AsyncCallback(ClientDisconnected), null);
private void ClientDisconnected(IAsyncResult ar)
{
// here get some client info like Ip
}
private void ClientConnected(IAsyncResult ar)
{
// here get some client info like Ip
}
I need some help please. Thanks.
BeginConnect() and BeginDisconnect() are asynchronous operations. They are not events you can subscribe to.
BeginConnect() is for a client socket to asynchronously open a new connection to a server. BeginDisconnect() asynchronously closes an open socket.
To detect clients connecting to your server, you need to use Accept(), BeginAccept()/EndAccept(), or AcceptAsync() to accept inbound connections coming into your server socket. You will be given a new Socket for each accepted client to use for communicating with them.
There is no event for a client disconnecting from a server. If a client disconnects, pending/subsequent send/receive operations involving that client will fail. You need to handle those failures when they occur. For instance, if a client disconnects gracefully, a read operation from the client will end as successful with 0 bytes reported. But if the client disconnects abnormally, a read operation will end as failed with an error code reported.
I've implemented a Xamarin app that successfully peers to another instance of itself running on another device using WiFiP2PManager, OnPeersAvailable and OnConnectionInfoAvailable (etc.).
My challenge now is I'd like the group owner to specify the PORT the client(s) will use to connect.
SERVER
var serverSocket = new ServerSocket(port); <<< PASS THIS PORT NUMBER TO THE CLIENT.
client = serverSocket.Accept();
CLIENT
client = new Socket();
InetSocketAddress socketAddress = new InetSocketAddress(address, port); <<< PORT PASSED FROM THE SERVER
client.Connect(socketAddress);
Is there any way I can pass additional information to the peer that it can use for connection, such as the port number?
Thanks
-John
I am developing an application in which i am using socket for the communication between server application and client application(web and desktop both). My server application continuously listening the request of the client application and accept the request whenever comes.
Server code :
TcpListener listener = new TcpListener(IPAddress.Parse(ipAddStr), portNum);
listener.Start();
while (listen)
{
TcpClient handler = listener.AcceptTcpClient();
// doing some stuff
// for every client handler i am creating a new thread and start listening for the next request
}
and for web client i am using WebSocket, as for establishing the connection with WebSocket client we have to follow some handshaking process. and for that I am using the following code (which is working fine) :
static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
private static string AcceptKey(ref string key)
{
string longKey = key + guid;
SHA1 sha1 = SHA1CryptoServiceProvider.Create();
byte[] hashBytes = sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(longKey));
return Convert.ToBase64String(hashBytes);
}
generating and sending response for handshaking with websocket client:
// generate accept key fromm client header request
var key = headerRequest.Replace("ey:", "`")
.Split('`')[1]
.Replace("\r", "").Split('\n')[0]
.Trim();
var responseKey = AcceptKey(ref key);
//create the response for the webclient
var newLine = "\r\n";
var response = "HTTP/1.1 101 Switching Protocols" + newLine
+ "Upgrade: websocket" + newLine
+ "Connection: Upgrade" + newLine
+ "Sec-WebSocket-Accept: " + responseKey + newLine + newLine;
//send respose to the webclient
Byte[] sendBytes = Encoding.ASCII.GetBytes(response);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
I have also TcpClient socket used for desktop application, so the problem is how to identify that the request is from WebSocket or from TcpClient ?
The easiest way would be to have a websocket listener and the vanilla TCP listener listen to different port numbers. You should do that anyway, because it is customary for websocket applications to run on the standard http port 80 (or standard https port 443 when you use websockets with TLS), while a custom protocol based on TCP should run on one of the ports from the "registered" range between 1024 to 49151. You are well-advised to follow this, because a well-secured client environment which allows web access but not much else might not allow the user to connect to other ports than 80 and 443, while any non-http traffic on these ports might trigger an intrusion detection system.
When you still want to handle both protocols on the same port for some reason, it will be a bit difficult. Websocket is a protocol based on TCP which looks like a vanilla HTTP GET request at first, until you receive the headers Connection: Upgrade and Upgrade: websocket.
That means connection requests for either protocol need to be accepted by the same listener at first. Only after the client sent enough data to identify its connection attempt as either your custom protocol or websocket (or something completely different which accidentally connected to your port - you will encounter that a lot when you deploy your application facing the internet) and then delegate the communication with the client to the appropriate handler class.
A TcpClient is a Socket wrapper.
WebSocket is a protocol that can run over a TcpClient. WebSocket protocol defines the handshake and how to frame data.
The best way of differentiate simple TCP connections and WebSocket connections is to have them listening in different ports, since you are going to use different protocols. It would be bad if you have them in the same port, it will become a mess.
So I am very new to networking and the Socket module in Python. So I watched some Youtube tutorials and found one on how to write the code for a simple server. My problem is right when the server receives data from the client, the server close() and loses connection to the client right when it receives the data. I want the server to automatically lose connection to the client but not "shutdown" or close(). I want to set it (if its possible) so that while the server is running in my Python Shell, if I want to close() the connection I use hot keys like for example "Control+E"? Here is my code so far:
#!/usr/bin/python
import socket
import sys
# Create a TCP/IP socket to listen on
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Prevent from "adress already in use" upon server restart
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind the socket to port 8081 on all interfaces
server_address = ('localhost',8081)
print ('starting up on %s port %s')%(server_address)
server.bind(server_address)
#Listen for connections
server.listen(5)
#Wait for one incoming connection
connection, client_address = server.accept()
print 'connection from', connection.getpeername()
# Let's recieve something
data = connection.recv(4096)
if data:
print "Recived ", repr(data)
#send the data back nicely formatted
data = data.rstrip()
connection.send("%s\n%s\n%s\n"%('-'*80, data.center(80),'-'*80))
# lose the connection from our side (the Server side)
connection.shutdown(socket.SHUT_RD | socket.SHUT_WR)
connection.close()
print 'Connection closed'
# And stop listening
server.close()
==================================================================================
Here is the code I am using (on the server side):
#!/usr/bin/python
import socket, sys
import select
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Let's set the socket option reuse to 1, so that our server terminates quicker
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("localhost", 8081))
srv.listen(5)
while True:
print "Waiting for a client to connect"
(client, c_address) = srv.accept() #blocking wait for client
print "Client connected"
# Client has connected, add him to a list which we can poll for data
client_list = [client]
while close_socket_condition == 0:
ready_to_read, ready_to_write, in_error = select.select(client_list, [], [] , 1) #timeout 1 second
for s in ready_to_read: #Check if there is any socket that has data ready for us
data = client.recv(1024) # blocks until some data is read
if data:
client.send("echo:" + data)
client.close()
close_socket_condition = 1
And here is the error it is giving me when I try to send a string to the server:
data = s.recv(1024)
File "C:\Python27\lib\socket.py", line 170, in _dummy
raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor
Here is example on a non-blocking socket read with similar structure as yours.
The server will establish a socket in localhost, and wait for a client to connect. After that it will start polling the socket for data, and also keep checking the exit condition close_socket_condition. Handling ctrl-e or other exit events will be left as an exercise :)
First we start socket, very much the same way as you:
#!/usr/bin/python
import socket, sys
import select
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Let's set the socket option reuse to 1, so that our server terminates quicker
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("localhost", 8081))
srv.listen(5)
Then we declare our external exit condition close_socket_condition, and start eternal while loop that will always welcome new clients:
close_socket_condition = 0
while True:
print "Waiting for a client to connect"
(client, c_address) = srv.accept() #blocking wait for client
print "Client connected"
Now a client has connected, and we should start our service loop:
# Client has connected, add him to a list which we can poll for data
client_list = [client]
while close_socket_condition == 0:
Inside the service loop we will keep polling his socket for data and if nothing has arrived, we check for exit condition:
ready_to_read, ready_to_write, in_error = select.select(client_list, [], [] , 1) #timeout 1 second
for s in ready_to_read: #Check if there is any socket that has data ready for us
data = client.recv(1024) # blocks until some data is read
if data:
client.send("echo:" + data)
client.close()
close_socket_condition = 1
This code is simplified example, but the server will keep accepting new clients, and always reuse the connection. It does not handle client side terminations etc.
Hope it helps