I have developed UDP multicast server in c# and UDP multicast reciever in Android,but iam not able to recieve data from server to client(Android).Is it because of the port numbers
i have used in code ? Your help is greatly appretiated and will save me nights.
***Server code
namespace Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
UdpClient udpclient = new UdpClient();
IPAddress multicastaddress = IPAddress.Parse("233.45.17.10");
udpclient.JoinMulticastGroup(multicastaddress);
IPEndPoint remoteep = new IPEndPoint(multicastaddress, 10000);
Byte[] buffer = null;
for (int i=1;i<30;i++)
{
buffer = Encoding.Unicode.GetBytes(i.ToString());
int flag = udpclient.Send(buffer, buffer.Length, remoteep);
}
MessageBox.Show("Data Sent TO " + ip.Text + "On Port " + port.Text);
status.Text = "Connected";
}
private void disconnect_Click(object sender, EventArgs e)
{
this.Close();
}
}
}***
Client code(Android):
public class TestMulticast extends Activity
{
static boolean done = false;
EditText et;
TextView tv;
Button b;
MulticastSocket socket;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b=(Button)findViewById(R.id.b);
et=(EditText)findViewById(R.id.et);
tv =(TextView)findViewById(R.id.tv);
b.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
try
{
String msg = et.getText().toString();
socket.send(new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, InetAddress.getByName("192.168.1.6"), 10000));
Toast.makeText(getApplicationContext(), "sent", 100).show();
}
catch (Exception e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
if (!done)
{
try
{
WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiinfo = wifiManager.getConnectionInfo();
int intaddr = wifiinfo.getIpAddress();
if (intaddr == 0)
{
tv.setText("Unable to get WIFI IP address");
}
else
{
byte[] byteaddr = null;
byteaddr = new byte[] {
(byte)(intaddr & 0xff),
(byte)(intaddr >> 8 & 0xff),
(byte)(intaddr >> 16 & 0xff),
(byte)(intaddr >> 24 & 0xff)
};
String machineName = "androidtestdevice";
InetAddress addr = InetAddress.getByAddress(machineName, byteaddr);
tv.append("Using address: " + addr + "\n");
Toast.makeText(getApplicationContext(), "using address"+addr, 50).show();
// create socket
socket = new MulticastSocket(11111);
// set network interface
NetworkInterface iface = NetworkInterface.getByInetAddress(addr);
Toast.makeText(getApplicationContext(), "First address on interface is: " + getAddressFor(iface), 50).show();
tv.append("First address on interface is: " + getAddressFor(iface) + "\n");
// The following line throws an exception in Android (Address is not available)
// If it's not called, the socket can receives packets
// Equivalent code in seems to C work.
//socket.setNetworkInterface(iface);
// join group
socket.joinGroup(InetAddress.getByName("233.45.17.10"));
tv.append("It worked\n");
// start receiving
new DatagramListener(socket, tv).start();
}
}
catch (Exception e) {
tv.append(e.toString() + "\n");
e.printStackTrace();
}
}
}
class DatagramListener extends Thread {
private DatagramSocket socket;
private TextView tv;
DatagramListener(DatagramSocket s, TextView tv) {
socket = s;
this.tv = tv;
}
public void run() {
byte[] buf = new byte[1000];
try {
while (true) {
DatagramPacket recv = new DatagramPacket(buf, buf.length);
socket.receive(recv);
System.out.println("received: " + new String(recv.getData(), recv.getOffset(), recv.getLength()));
runOnUiThread(new MyRunnable(new String(recv.getData(), recv.getOffset(), recv.getLength()), tv));
Toast.makeText(getApplicationContext(), "Now showing data", Toast.LENGTH_SHORT).show();
}
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "received: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
static private class MyRunnable implements Runnable {
private TextView tv;
private String text;
public MyRunnable(String text, TextView tv) {
this.tv = tv;
this.text = text;
}
public void run() {
tv.append(text + "\n");
}
}
public static InetAddress getAddressFor(NetworkInterface iface) {
Enumeration<InetAddress> theAddresses = iface.getInetAddresses();
boolean found = false;
InetAddress firstAddress = null;
while ((theAddresses.hasMoreElements()) && (found != true)) {
InetAddress theAddress = theAddresses.nextElement();
if (theAddress instanceof Inet4Address) {
firstAddress = theAddress;
found = true;
}
}
return firstAddress;
}
}
Multicast packets are filtered in many android devices depending on vendor (some do others don't htc would filter it most likely), presumably to save battery. it is not blocked in android as such but the vendors.
Related
I am trying to understand the correct way of how should I make good multithreaded TCP server.
Here is what I have so far:
public class WorldServer
{
public List<ServerClient> clients = new List<ServerClient>();
public int port = 8080;
public TcpListener server;
private bool serverStarted;
private int connectionIncrementor;
private MySQLConnection mySQLConnection = new MySQLConnection();
private MySqlConnection mysqlConn = null;
static void Main(string[] args)
{
WorldServer serverInstance = new WorldServer();
Console.WriteLine("Starting World Server...");
try
{
serverInstance.mysqlConn = new MySqlConnection(serverInstance.mySQLConnection.mysqlConnectionString);
serverInstance.mysqlConn.Open();
Console.WriteLine("Connected to MySQL version: " + serverInstance.mysqlConn.ServerVersion + "\n");
}
catch (Exception e)
{
Console.WriteLine("MySQL Error: " + e.ToString());
}
finally
{
if (serverInstance.mysqlConn != null)
{
serverInstance.mysqlConn.Close();
}
}
serverInstance.clients = new List<ServerClient>();
try
{
serverInstance.server = new TcpListener(IPAddress.Any, serverInstance.port);
serverInstance.server.Start();
serverInstance.StartListening();
serverInstance.serverStarted = true;
Console.WriteLine("Server has been started on port: " + serverInstance.port);
}
catch (Exception e)
{
Console.WriteLine("Socket error: " + e.Message);
}
while (true)
{
serverInstance.Update();
}
}
private void Update()
{
//Console.WriteLine("Call");
if (!serverStarted)
{
return;
}
foreach (ServerClient c in clients.ToList())
{
//Check if TCP is not null
if (c.tcp == null)
return;
// Is the client still connected?
if (!IsConnected(c.tcp))
{
c.tcp.Close();
clients.Remove(c);
Console.WriteLine(c.connectionId + " has disconnected.");
continue;
//Console.WriteLine("Check for connection?\n");
}
else
{
// Check for message from Client.
NetworkStream s = c.tcp.GetStream();
if (s.DataAvailable)
{
string data = c.streamReader.ReadLine();
if (data != null)
{
if (ValidateJSON(data))
{
Thread incomingData = new Thread(() => OnIncomingData(c, data));
incomingData.Start();
}
}
}
//continue;
}
}
}
public bool ValidateJSON(string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
private void OnIncomingData(ServerClient c, string data)
{
dynamic json = JsonConvert.DeserializeObject(data);
string header = json.header;
//Console.WriteLine("HEADER ID:" + json.header);
string connId = json.connectionId;
int.TryParse(connId, out int connectionId);
int characterId = 0;
Dictionary<string, string> receivedData = new Dictionary<string, string>();
if (json.data != null)
{
receivedData = json.data.ToObject<Dictionary<string, string>>();
}
if (json.data["characterId"] != null)
{
characterId = json.data["characterId"];
}
string prefix = header.Substring(0, 2);
if (prefix != "1x")
{
Console.WriteLine("Unknown packet: " + data + "\n");
}
else
{
string HeaderPacket = header.Substring(2);
switch (HeaderPacket)
{
default:
Console.WriteLine("Unknown packet: " + data + "\n");
break;
case "004":
Console.WriteLine("Test Packet"); ;
break;
}
}
//Broadcast(null, data, clients);
//Console.WriteLine(c.clientName + " has sent the following message :" + data);
}
public bool IsConnected(TcpClient c)
{
try
{
if (c != null && c.Client != null && c.Client.Connected)
{
if (c.Client.Poll(0, SelectMode.SelectRead))
{
return !(c.Client.Receive(new byte[1], SocketFlags.Peek) == 0);
}
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
private void StartListening()
{
server.BeginAcceptTcpClient(OnConnection, server);
}
private void OnConnection(IAsyncResult ar)
{
connectionIncrementor++;
TcpListener listener = (TcpListener)ar.AsyncState;
clients.Add(new ServerClient(listener.EndAcceptTcpClient(ar)));
clients[clients.Count - 1].connectionId = connectionIncrementor;
StartListening();
//Send a message to everyone, say someone has connected!
Dictionary<string, object> SendDataBroadcast = new Dictionary<string, object>();
SendDataBroadcast.Add("connectionId", clients[clients.Count - 1].connectionId);
Broadcast("001", SendDataBroadcast, clients[clients.Count - 1].connectionId);
Console.WriteLine(clients[clients.Count - 1].connectionId + " has connected.");
}
public void Broadcast(string header, Dictionary<string, object> data, int cnnId = 0)
{
string jsonData = JsonConvert.SerializeObject(data, Formatting.Indented);
foreach (ServerClient c in clients)
{
try
{
if (header == null)
{
header = "000";
}
JsonData SendData = new JsonData();
SendData.header = "0x" + header;
SendData.data = JObject.Parse(jsonData);
SendData.connectionId = cnnId;
string JSonData = JsonConvert.SerializeObject(SendData);
//Console.WriteLine("SENDING: " + JSonData);
c.streamWriter.WriteLine(JSonData);
c.streamWriter.Flush();
}
catch (Exception e)
{
Console.WriteLine("Write error : " + e.Message + " to client " + c.connectionId);
}
}
}
public void Send(string header, Dictionary<string, object> data, int cnnId)
{
string jsonData = JsonConvert.SerializeObject(data, Formatting.Indented);
foreach (ServerClient c in clients.ToList())
{
if (c.connectionId == cnnId)
{
try
{
//Console.WriteLine("Sending...");
if (header == null)
{
header = "000";
}
JsonData SendData = new JsonData();
SendData.header = "0x" + header;
SendData.data = JObject.Parse(jsonData);
SendData.connectionId = cnnId;
string JSonData = JsonConvert.SerializeObject(SendData);
c.streamWriter.WriteLine(JSonData);
c.streamWriter.Flush();
//Console.WriteLine("Trying to send data to connection id: " + cnnId + " data:" + sendData);
}
catch (Exception e)
{
Console.WriteLine("Write error : " + e.Message + " to client " + c.connectionId);
}
}
}
}
}
public class ServerClient
{
public TcpClient tcp;
public StreamReader streamReader;
public StreamWriter streamWriter;
public int accountId;
public int connectionId;
public ServerClient(TcpClient clientSocket)
{
tcp = clientSocket;
streamReader = new StreamReader(tcp.GetStream(), false);
streamWriter = new StreamWriter(tcp.GetStream());
clientSocket.NoDelay = true;
}
}
The TCP server works. However I am really not sure if this is the best approach I can take.
Have I made the multi-threading well ? Probably not. I would like to receive advices where i can make it better.
Do I need to create a new thread on every OnIncomingData ?
Do I need to create new thread on every Send and Broadcast ?
Very often I receive error here foreach (ServerClient c in clients.ToList()). What can be the cause of it ?
What parts of the client is good to be multithreaded also aka the listening function for incoming data or the sending functions?
All advices are most welcome!
I wrote code for an OP last year that was a TCP Server and wrote to a SQL Server. I modified that code a few minutes ago to make it more general. The changes are not tested but original code worked very well. I used Asynchronous Send and Receive. I also used a fifo to send messages from the transport layer to the application layer. See code below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Data;
using System.Data.SqlClient;
using System.Timers;
using System.Threading;
namespace TCP_Server
{
public class StateObject
{
public long connectionNumber = -1;
public Socket workSocket { get; set; }
public byte[] buffer { get; set; }
public int fifoCount { get; set; }
}
public enum PROCESS_STATE
{
ACCEPT,
READ,
PROCESS,
UNPACK
}
public enum UNPACK_STATUS
{
ERROR,
NOT_ENOUGH_BYTES,
BAD_CRC,
GOOD_MESSAGE,
DEFAULT
}
public enum PROTOCOL_NUMBER
{
LOGIN_MESSAGE,
NONE
}
class Program
{
const string IP = "127.0.0.1";
const int PORT = 8841;
const Boolean test = true;
static void Main(string[] args)
{
Server server = new Server(IP, PORT, test);
Console.WriteLine("Connection Ended");
}
}
public class Server
{
const int BUFFER_SIZE = 1024;
const string CONNECT_STRING = #"Data Source=.\SQLEXPRESS;Initial Catalog=MyDataTable;Integrated Security=SSPI;";
const string LOGIN_INSERT_COMMMAND_TEXT = "use MyTable INSERT INTO Login (TerminalID,Date) VALUES(#TerminalID,#Date)";
const string LOCATION_INSERT_COMMMAND_TEXT = "INSERT INTO MyTable (CurrTime, Message)" +
"VALUES (#CurrTime, #Message)";
static SqlConnection conn = null;
static SqlCommand cmdLogin = null;
static SqlCommand cmdLocation = null;
static long connectionNumber = 0;
//mapping of connection number to StateObject
static Dictionary<long, KeyValuePair<List<byte>, StateObject>> connectionDict = new Dictionary<long, KeyValuePair<List<byte>, StateObject>>();
//fifo contains list of connections number wait with receive data
public static List<long> fifo = new List<long>();
public static AutoResetEvent allDone = new AutoResetEvent(false);
public static AutoResetEvent acceptDone = new AutoResetEvent(false);
public enum DATABASE_MESSAGE_TYPE
{
LOGIN,
LOCATION
}
public class WriteDBMessage
{
public DATABASE_MESSAGE_TYPE message { get; set; }
}
public class WriteDBMessageLogin : WriteDBMessage
{
public DateTime date { get; set; }
public string message { get; set; }
}
public class WriteDBMessageLocation : WriteDBMessage
{
public DateTime currTime { get; set; }
public byte[] message { get; set; }
}
public static class WriteDBAsync
{
public enum Mode
{
READ,
WRITE
}
public static List<WriteDBMessage> fifo = new List<WriteDBMessage>();
public static System.Timers.Timer timer = null;
public static void WriteDatabase()
{
timer = new System.Timers.Timer(1000);
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
public static WriteDBMessage ReadWriteFifo(Mode mode, WriteDBMessage message)
{
Object thisLock2 = new Object();
lock (thisLock2)
{
switch (mode)
{
case Mode.READ:
if (fifo.Count > 0)
{
message = fifo[0];
fifo.RemoveAt(0);
}
break;
case Mode.WRITE:
fifo.Add(message);
break;
}
}
return message;
}
static void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Enabled = false;
WriteDBMessage row = null;
int rowsAdded = 0;
uint number = 0;
try
{
while ((row = ReadWriteFifo(Mode.READ, null)) != null)
{
switch (row.message)
{
case DATABASE_MESSAGE_TYPE.LOGIN:
cmdLogin.Parameters["#Date"].Value = ((WriteDBMessageLogin)row).date;
rowsAdded = cmdLogin.ExecuteNonQuery();
break;
}
}
}
catch (Exception ex)
{
//Console.WriteLine("Error : '{0}'", ex.Message);
}
timer.Enabled = true;
}
}
public Server(string IP, int port, Boolean test)
{
try
{
conn = new SqlConnection(CONNECT_STRING);
conn.Open();
cmdLogin = new SqlCommand(LOGIN_INSERT_COMMMAND_TEXT, conn);
cmdLogin.Parameters.Add("#TerminalID", SqlDbType.NVarChar, 8);
cmdLogin.Parameters.Add("#Date", SqlDbType.DateTime);
cmdLocation = new SqlCommand(LOCATION_INSERT_COMMMAND_TEXT, conn);
cmdLocation.Parameters.Add("#IMEI", SqlDbType.NVarChar, 50);
cmdLocation.Parameters.Add("#TrackTime", SqlDbType.DateTime);
cmdLocation.Parameters.Add("#currTime", SqlDbType.DateTime);
cmdLocation.Parameters.Add("#Longitude", SqlDbType.NChar, 50);
cmdLocation.Parameters.Add("#Lattitude", SqlDbType.NVarChar, 50);
cmdLocation.Parameters.Add("#speed", SqlDbType.Float);
}
catch (Exception ex)
{
Console.WriteLine("Error : '{0}'", ex.Message);
//Console.ReadLine();
return;
}
try
{
//initialize the timer for writing to database.
WriteDBAsync.WriteDatabase();
StartListening(IP, port, test);
// Open 2nd listener to simulate two devices, Only for testing
//StartListening(IP, port + 1, test);
ProcessMessages();
}
catch (Exception ex)
{
Console.WriteLine("Error : '{0}'", ex.Message);
//Console.ReadLine();
return;
}
}
public void StartListening(string IP, int port, Boolean test)
{
try
{
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.GetHostEntry(IP); //Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
//IPAddress local = IPAddress.Parse(IP);
IPEndPoint localEndPoint = null;
if (test)
{
localEndPoint = new IPEndPoint(IPAddress.Any, port);
}
else
{
localEndPoint = new IPEndPoint(ipAddress, port);
}
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
allDone.Reset();
acceptDone.Reset();
listener.Bind(localEndPoint);
listener.Listen(100);
//login code, wait for 1st message
Console.WriteLine("Wait 5 seconds for login message");
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void ProcessMessages()
{
UInt16 sendCRC = 0;
DateTime date;
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int minute = 0;
int second = 0;
KeyValuePair<List<byte>, StateObject> byteState;
KeyValuePair<UNPACK_STATUS, byte[]> status;
byte[] receiveMessage = null;
StateObject state = null;
byte[] serialNumber = null;
byte[] serverFlagBit = null;
byte[] stringArray = null;
string stringMessage = "";
byte lengthOfCommand = 0;
PROTOCOL_NUMBER protocolNumber = PROTOCOL_NUMBER.NONE;
try
{
Boolean firstMessage = true;
acceptDone.Set();
//loop forever
while (true)
{
allDone.WaitOne();
//read fifo until empty
while (true)
{
//read one connection until buffer doesn't contain any more packets
byteState = ReadWrite(PROCESS_STATE.PROCESS, null, null, -1);
if (byteState.Value.fifoCount == -1) break;
state = byteState.Value;
while (true)
{
status = Unpack(byteState);
if (status.Key == UNPACK_STATUS.NOT_ENOUGH_BYTES)
break;
if (status.Key == UNPACK_STATUS.ERROR)
{
Console.WriteLine("Error : Bad Receive Message, Data");
break;
}
//message is 2 start bytes + 1 byte (message length) + 1 byte message length + 2 end bytes
receiveMessage = status.Value;
int messageLength = receiveMessage[2];
Console.WriteLine("Status : '{0}', Receive Message : '{1}'", status.Key == UNPACK_STATUS.GOOD_MESSAGE ? "Good" : "Bad", BytesToString(receiveMessage.Take(messageLength + 5).ToArray()));
if (status.Key != UNPACK_STATUS.GOOD_MESSAGE)
{
break;
}
else
{
if (firstMessage)
{
if (receiveMessage[3] != 0x01)
{
Console.WriteLine("Error : Expected Login Message : '{0}'", BytesToString(receiveMessage));
break;
}
firstMessage = false;
}
//skip start bytes, message length. then go back 4 bytes (CRC and serial number)
serialNumber = receiveMessage.Skip(2 + 1 + messageLength - 4).Take(2).ToArray();
protocolNumber = (PROTOCOL_NUMBER)receiveMessage[3];
Console.WriteLine("Protocol Number : '{0}'", protocolNumber.ToString());
switch (protocolNumber)
{
case PROTOCOL_NUMBER.LOGIN_MESSAGE:
break;
} //end switch
}// End if
} //end while
}//end while fifo > 0
allDone.Reset();
}//end while true
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
static string BytesToString(byte[] bytes)
{
return string.Join("", bytes.Select(x => x.ToString("X2")));
}
static KeyValuePair<UNPACK_STATUS, byte[]> Unpack(KeyValuePair<List<byte>, StateObject> bitState)
{
List<byte> working_buffer = bitState.Key;
//return null indicates an error
if (working_buffer.Count() < 3) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.NOT_ENOUGH_BYTES, null);
int len = working_buffer[2];
if (working_buffer.Count < len + 5) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.NOT_ENOUGH_BYTES, null);
// check start and end bytes
// remove message fro workig buffer and dictionary
KeyValuePair<List<byte>, StateObject> byteState = ReadWrite(PROCESS_STATE.UNPACK, null, null, bitState.Value.connectionNumber);
if (byteState.Key.Count == 0) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.ERROR, null);
List<byte> packet = byteState.Key;
//crc test
byte[] crc = packet.Skip(len + 1).Take(2).ToArray();
ushort crcShort = (ushort)((crc[0] << 8) | crc[1]);
//skip start bytes, crc, and end bytes
return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.GOOD_MESSAGE, packet.ToArray());
}
static KeyValuePair<List<byte>, StateObject> ReadWrite(PROCESS_STATE ps, Socket handler, IAsyncResult ar, long unpackConnectionNumber)
{
KeyValuePair<List<byte>, StateObject> byteState = new KeyValuePair<List<byte>, StateObject>(); ;
StateObject stateObject = null;
int bytesRead = -1;
int workingBufferLen = 0;
List<byte> working_buffer = null;
byte[] buffer = null;
Object thisLock1 = new Object();
lock (thisLock1)
{
switch (ps)
{
case PROCESS_STATE.ACCEPT:
acceptDone.WaitOne();
acceptDone.Reset();
stateObject = new StateObject();
stateObject.buffer = new byte[BUFFER_SIZE];
connectionDict.Add(connectionNumber, new KeyValuePair<List<byte>, StateObject>(new List<byte>(), stateObject));
stateObject.connectionNumber = connectionNumber++;
stateObject.workSocket = handler;
byteState = new KeyValuePair<List<byte>, StateObject>(null, stateObject);
acceptDone.Set();
break;
case PROCESS_STATE.READ:
//catch when client disconnects
//wait if accept is being called
//acceptDone.WaitOne();
try
{
stateObject = ar.AsyncState as StateObject;
// Read data from the client socket.
bytesRead = stateObject.workSocket.EndReceive(ar);
if (bytesRead > 0)
{
byteState = connectionDict[stateObject.connectionNumber];
buffer = new byte[bytesRead];
Array.Copy(byteState.Value.buffer, buffer, bytesRead);
byteState.Key.AddRange(buffer);
}
//only put one instance of connection number into fifo
if (!fifo.Contains(byteState.Value.connectionNumber))
{
fifo.Add(byteState.Value.connectionNumber);
}
}
catch (Exception ex)
{
//will get here if client disconnects
fifo.RemoveAll(x => x == byteState.Value.connectionNumber);
connectionDict.Remove(byteState.Value.connectionNumber);
byteState = new KeyValuePair<List<byte>, StateObject>(new List<byte>(), null);
}
break;
case PROCESS_STATE.PROCESS:
if (fifo.Count > 0)
{
//get message from working buffer
//unpack will later delete message
//remove connection number from fifo
// the list in the key in known as the working buffer
byteState = new KeyValuePair<List<byte>, StateObject>(connectionDict[fifo[0]].Key, connectionDict[fifo[0]].Value);
fifo.RemoveAt(0);
//put a valid value in fifoCount so -1 below can be detected.
byteState.Value.fifoCount = fifo.Count;
}
else
{
//getting here is normal when there is no more work to be performed
//set fifocount to zero so rest of code know fifo was empty so code waits for next receive message
byteState = new KeyValuePair<List<byte>, StateObject>(null, new StateObject() { fifoCount = -1 });
}
break;
case PROCESS_STATE.UNPACK:
try
{
working_buffer = connectionDict[unpackConnectionNumber].Key;
workingBufferLen = working_buffer[2];
if ((working_buffer[0] != 0x78) && (working_buffer[1] != 0x78) && (working_buffer[workingBufferLen + 3] != 0x0D) && (working_buffer[workingBufferLen + 4] != 0x0A))
{
working_buffer.Clear();
return new KeyValuePair<List<byte>, StateObject>(new List<byte>(), null);
}
List<byte> packet = working_buffer.GetRange(0, workingBufferLen + 5);
working_buffer.RemoveRange(0, workingBufferLen + 5);
byteState = new KeyValuePair<List<byte>, StateObject>(packet, null);
}
catch (Exception ex)
{
int testPoint = 0;
}
break;
}// end switch
}
return byteState;
}
public static void AcceptCallback(IAsyncResult ar)
{
try
{
// Get the socket that handles the client request.
// Retrieve the state object and the handler socket
// from the asynchronous state object.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = ReadWrite(PROCESS_STATE.ACCEPT, handler, ar, -1).Value;
handler.BeginReceive(state.buffer, 0, BUFFER_SIZE, 0,
new AsyncCallback(ReadCallback), state);
}
catch (Exception ex)
{
int myerror = -1;
}
}
public static void ReadCallback(IAsyncResult ar)
{
try
{
StateObject state = ar.AsyncState as StateObject;
Socket handler = state.workSocket;
// Read data from the client socket.
KeyValuePair<List<byte>, StateObject> byteState = ReadWrite(PROCESS_STATE.READ, handler, ar, -1);
if (byteState.Value != null)
{
allDone.Set();
handler.BeginReceive(state.buffer, 0, BUFFER_SIZE, 0,
new AsyncCallback(ReadCallback), state);
}
else
{
int testPoint = 0;
}
}
catch (Exception ex)
{
int myerror = -1;
}
// Signal the main thread to continue.
allDone.Set();
}
}
}
I am trying to On/Off a led from desktop app on C# to Arduino using Ethernet (for serial port communication works), I am connecting to an IP Address to communicate with Arduino, but it looks something wrong with my code or my sketch for Arduino. (I am working with Ethernet shield)
my code Arduino
//////////INCLUDE HEADER FILES //////////////////
#include <Ethernet.h>
#include <SPI.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <SD.h>
#include <Wire.h>
EthernetServer server(23 );
String content;
File myFile;
int ledPin = 7;
int outputpin = 0;
void setup()
{
IPAddress ip( 192, 168,1,110);
byte mac[] = {
0xDE,0xAE,0xBE,0xEF,0xFE,0xED
};
Ethernet.begin( mac, ip );
server.begin();
if ( ! SD.begin( 4 ) )
{
return;
}
Serial.begin(9600);
}
void loop()
{
waitIncommingConnection();
}
void waitIncommingConnection()
{
String pwd = "";
String inData = "";
EthernetClient client = server.available();
if ( client )
{
while ( client.connected() )
{
if ( client.available() > 0)
{
char recieved = client.read();
inData += recieved;
if (recieved == '\n')
{
switch( inData[0] )
{
case (char)'o' :
client.println("o");
digitalWrite(ledPin, HIGH);
break;
case (char)'f' :
client.println("f");
digitalWrite(ledPin, LOW);
break;
case (char)'*' :
Logout(client);
break;
default:
client.println('d');
break;
}
inData = "";
}
}
}
}
else
{
client.println('v');
}
}
void Logout(EthernetClient client )
{
client.print('x');
client.stop();
}
My C# code
public partial class Form1 : Form
{
public Client client;
public delegate void FeedBackCallback(string text);
public delegate void UpdateMessageBoxCallback(string text);
public Form1()
{
InitializeComponent();
}
private void connect_Click(object sender, EventArgs e)
{
string ipAddr = ip1.Text + "." + ip2.Text + "." + ip3.Text + "." + ip4.Text;
string port = portInput.Text;
if (IsValidIPAddress(ipAddr) == true)
{
try
{
if (client == null)
client = new Client(this);
client.Connect(ipAddr, port);
// client.Send(Encoding.GetEncoding(Constant.EncodingFormat).GetBytes("c"+'\n'));
disconect.Enabled = true;
connect.Enabled = false;
on.Enabled = true;
}
catch (SocketException se)
{
MessageBox.Show("Unable to Connect.\r\n" + se.ToString());
}
}
else
{
MessageBox.Show("Invaild Ip Adrress", "Invaild Ip Adrress", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private bool IsEmptyUserNamePasswordFields(string userName, string password)
{
if (userName.Length == 0 || password.Length == 0)
{
MessageBox.Show("Password and Username field is required!", "Required Fileds Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
else
{
return true;
}
}
private bool IsValidIPAddress(string ipaddr)//Validate the input IP address
{
try
{
IPAddress.Parse(ipaddr);
return true;
}
catch (Exception e)
{
return false;
}
}
private void on_Click(object sender, EventArgs e)
{
disconect.PerformClick();
connect.PerformClick();
try
{
if (client == null)
client = new Client(this);
client.Send(Encoding.GetEncoding(Constant.EncodingFormat).GetBytes("o" + '\n'));
off.Enabled = true;
on.Enabled = false;
}
catch (SocketException se)
{
MessageBox.Show("Unable to Connect.\r\n" + se.ToString());
}
}
private void off_Click(object sender, EventArgs e)
{
disconect.PerformClick();
connect.PerformClick();
try
{
if (client == null)
client = new Client(this);
client.Send(Encoding.GetEncoding(Constant.EncodingFormat).GetBytes("f" + '\n'));
on.Enabled = true;
off.Enabled = false;
}
catch (SocketException se)
{
MessageBox.Show("Unable to Connect.\r\n" + se.ToString());
}
}
private void disconect_Click(object sender, EventArgs e)
{
connect.Enabled = true;
disconect.Enabled = false;
client.Disconnect();
}
}
images for the Arduino
I don't know where is my problem, the app connect to the arduino, but the On/Off button not works for the led.
if u want to see the code foe serial port communication this is the link here, Serial Port
On my server side I have set up a single thread code that creates a new Socket object every time a client connects. Then I pass whatever I get from the client along with the socket that is connected to a packet handler and do the calculations there. In my main form I have a listview that I populate via entity framework, and whenever a packet from a registered computer connects I update the listview. So my question is can I from the packet handler class pass the socket object to the tag property of my listview when I update it?
My server side code:
private void ReceivedCallback(IAsyncResult result)
{
Socket clientSocket = result.AsyncState as Socket;
SocketError ER;
try
{
int bufferSize = clientSocket.EndReceive(result, out ER);
if (ER == SocketError.Success)
{
byte[] packet = new byte[bufferSize];
Array.Copy(_buffer, packet, packet.Length);
Console.WriteLine("Handling packet from IP:" + clientSocket.RemoteEndPoint.ToString());
//Handle packet stuff here.
PacketHandler.Handle(packet, clientSocket);
_buffer = new byte[61144];
clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
//clientSocket.BeginReceive(new byte[] { 0 }, 0, 0, 0, ReceivedCallback, clientSocket);
}
else
{
Console.WriteLine("No bytes received, we're closing the connection.");
clientSocket.Close();
}
}catch(SocketException ex)
{
Console.WriteLine("We caught a socket exception:" + ex.Message);
clientSocket.Close();
}
}
And my packet handler class:
public static void Handle(byte[] packet, Socket clientSocket)
{
if (clientSocket.Connected)
{
if (packet.Length > 0)
{
IPEndPoint RemoteIP = (IPEndPoint)clientSocket.RemoteEndPoint;
ushort packetLength = BitConverter.ToUInt16(packet, 0);
ushort packetType = BitConverter.ToUInt16(packet, 2);
ushort packetID = BitConverter.ToUInt16(packet, 4);
Console.WriteLine("We received a packet of Type: {0}, ID: {1} FROM {2}", packetType, packetID, RemoteIP.ToString());
if (packetType == 1)
{
switch (packetID)
{
case 1://Check if computer is registered in the database
CheckRegisteredRequest request1 = new CheckRegisteredRequest(packet);
Console.WriteLine("We received (Case 1): " + request1.Text);
string Response = "";
bool found = false;
ServerDbContext database = new ServerDbContext();
foreach (computers pcs in database.computers)
{
if (pcs.name == request1.Text.Split(',')[0])
{
found = true;
if (pcs.computer_ip == request1.Text.Split(',')[1])
{
//We found a computer with that name and ip address
Response = "true";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
computers registeredPC;
var name = request1.Text.Split(',')[0];
using (var ctx = new ServerDbContext())
{
registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
}
if (registeredPC != null)
{
registeredPC.networkStatus = "online";
}
using (var ctx = new ServerDbContext())
{
ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
break;
}
else
{
//We found a computer with that name but a different ip address, update it
var name = request1.Text.Split(',')[0];
var registeredPC = new computers();
using (var ctx = new ServerDbContext())
{
registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
}
if (registeredPC != null)
{
var ip = request1.Text.Split(',')[1];
registeredPC.computer_ip = ip;
registeredPC.networkStatus = "online";
}
using (var ctx = new ServerDbContext())
{
ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
Response = "true";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
break;
}
}
}
if (!found)
{
//There is no computer with that name in the database so send false
Response = "false";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
}
break;... and so on....
So I've tried via a handler:
this is my custom event handler Args:
public class TextArgs : EventArgs
{
#region Fields
private string szMessage;
private Socket _sockets123;
#endregion Fields
#region ConstructorsH
public TextArgs(string TextMessage,Socket sock)
{
if (sock != null)
{
_sockets123 = sock;
szMessage = TextMessage;
}
else
{
szMessage = TextMessage;
}
}
#endregion Constructors
#region Properties
public string Message
{
get { return szMessage; }
set { szMessage = value; }
}
public Socket _socket
{
get { return _sockets123; }
set { _sockets123 = value; }
}
#endregion Properties
}
This is how i define that handler at the PacketHandler class:
public static event LogsEventHandler Feedback;
private static void RaiseFeedback(string p, Socket sock)
{
LogsEventHandler handler = Feedback;
if (handler != null)
{
handler(null,new TextArgs(p,sock));
}
}
And whenever a computer registers or connects I do the following:
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], clientSocket);
or
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], null);
And the event fires of these two methods in my main form:
private void OnFeedbackReceived(object sender, TextArgs e)
{
Invoke((MethodInvoker)delegate
{
UpdateComputers();
UpdateGUI(e.Message,e._socket);
}
);
}
public void UpdateGUI(string s, Socket sock)
{
LogBox.Text += s;
LogBox.AppendText(Environment.NewLine);
using (var context = new ServerDbContext())
{
var PCInfo = context.viewUsersInfo;
dataGridView1.DataSource = PCInfo.ToList();
}
if (sock != null)
{
ListViewItem item = ComputersList.FindItemWithText(s.Split(':')[1].ToString());
item.Tag = sock;
}
}
The Question: Yes, you can. Control.Tag is of type object and can hold pretty much anything you choose.
So you can write
Socket socket = someSocket;
ListViewItem item = listView1.FindItemWithText(someText);
if (item != null) item.Tag = socket; else Console.WriteLine(someText + " not found!);
And retrieve it as:
if (item.Tag != null) someSocket = item.Tag AS socket;
if (someSocket != null) ..
It is up to you to watch out for the success of the cast when retrieving it but also if the Socket still is alive and well..
The problem: The stackoverflow in your code is due to an erreanous, short-circuited property, which you have fixed by now. In general, you only need to write explicit getter and setters if they actually do more than just gettin and setting.
They could log out out test data, update other, dependent properties, do checks or conversiones or do other stuff.
But if none of it is needed, simply don't create the private fields and write the automatic getter and setters:
public Socket MySocket {get; set;}
Also note that the naming convention asks you to capitalize proprety names!
My problem is only happening when I try to use my socket connection under a windows service.
Basically I have a socket client which connect to a remote server.
When I use it in a client application I don't have any problem at all.
But when I try to use it under my windows service it doesn't work.
public abstract class SocketClient
{
public static readonly ILog log = LogManager.GetLogger(typeof(SocketClient));
private System.Net.Sockets.Socket fSocket;
private bool LocalsocketClientIsShutingDown;
private byte[] readbuf;
private byte[] sendbuf;
private string currentmessage = "";
public event EventHandler ConnectionDone;
public event EventHandler ConnectionFailed;
public event EventHandler MessageReceivingFailed;
public event EventHandler MessageSendingFailed;
public SocketClient()
{
log4net.Config.XmlConfigurator.Configure();
readbuf = new byte[16384];
this.ConnectionDone += new EventHandler(OnSocketConnectionDone);
this.ConnectionFailed += new EventHandler(OnSocketConnectionFailed);
this.MessageSendingFailed += new EventHandler(OnMessageSendingFailed);
this.MessageReceivingFailed += new EventHandler(OnMessageReceivingFailed);
}
public bool isConnected()
{
if (fSocket == null)
return false;
return fSocket.Connected;
}
protected abstract void OnSocketConnectionDone(object sender, EventArgs e);
protected abstract void OnSocketConnectionFailed(object sender, EventArgs e);
protected abstract void OnMessageSendingFailed(object sender, EventArgs e);
protected abstract void OnMessageReceivingFailed(object sender, EventArgs e);
protected void ConnectToServer(string ServerName, int Port)
{
try
{
log.Debug("SocketClient.ConnectToServer():" + ServerName);
if (this.fSocket == null || !this.fSocket.Connected)
{
this.fSocket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream
, ProtocolType.Tcp);
IPAddress[] ipadress;
log.Debug("ConnectToServer()1");
IPHostEntry he = Dns.GetHostEntry(ServerName); //Dns.Resolve(ServerName);
log.Debug("ConnectToServer()2" + he.HostName);
ipadress = he.AddressList;
//he.AddressList = he.AddressList.ToList().Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToArray();
IPEndPoint remoteEP = new IPEndPoint(ipadress[0], Port);
if (ServerName=="localhost")
{
IPHostEntry ipHostInfo = /*Dns.Resolve*/Dns.GetHostEntry(Dns.GetHostName()); //Dns.Resolve(Dns.GetHostName());
//dont take IPv6 IPs
//ipHostInfo.AddressList = ipHostInfo.AddressList.ToList().Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToArray();
IPAddress ipAddress = ipHostInfo.AddressList[0];
remoteEP = new IPEndPoint(ipAddress, Port);
}
log.Debug("ConnectToServer()3: start BeginConnect()");
this.fSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback)
, this.fSocket);
Trace.WriteLine("Connecting to server");
}
else
{
Trace.WriteLine("Already connected to a Server");
}
}
catch (Exception ex)
{
Trace.WriteLine("Error connecting to server" + ex.ToString());
OnConnectionFailed();
}
}
private void ConnectCallback(IAsyncResult asyncResult)
{
string[] obj;
try
{
log.Debug("end BeginConnect with ConnectCallback()");
System.Net.Sockets.Socket socket = (System.Net.Sockets.Socket)asyncResult.AsyncState;
this.fSocket = socket;
socket.EndConnect(asyncResult);
this.LocalsocketClientIsShutingDown = false;
this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None
, new AsyncCallback(ReceiveCallback), this.fSocket);
OnConnectionDone();
}
catch (SocketException ex)
{
Trace.WriteLine("Connection Failed: " + ex.Message);
OnConnectionFailed();
}
}
private void OnConnectionDone()
{
log.Debug("OnConnectionDone");
if (ConnectionDone != null)
{
ConnectionDone(this, new EventArgs());
}
}
private void OnConnectionFailed()
{
log.Debug("OnConnectionFailed");
if (ConnectionFailed != null)
ConnectionFailed(this, new EventArgs());
}
public void SendMessage(string message)
{
log.Debug(">>> Sending Message: " + message);
if (this.fSocket != null && this.fSocket.Connected)
{
log.Debug(">>> Sending Message: Begin send 1:" + message);
//Turn string into byte for network transfer
this.sendbuf = Encoding.ASCII.GetBytes(message);
log.Debug(">>> Sending Message: Begin send 2:" + message);
this.fSocket.BeginSend(this.sendbuf, 0, this.sendbuf.Length, SocketFlags.None, new AsyncCallback(SendCallback)
, this.fSocket);
}
else
{
log.Debug("Cant Send Message: " + message + " _ Not connected to socket");
Trace.WriteLine("Not connected to Server");
}
}
private void SendCallback(IAsyncResult asyncResult)
{
try
{
//On récupere le socket sur lequel on a envoyé les données
System.Net.Sockets.Socket socket = (System.Net.Sockets.Socket)asyncResult.AsyncState;
//on met fin à l'envois de données
int senda = socket.ReceiveBufferSize;
int send = socket.EndSend(asyncResult);
Trace.WriteLine(">>> Message Sent: " + send + " bytes");
log.Debug(">>> Message Sent: " + send + " bytes");
}
catch (SocketException ex)
{
log.Debug("!!! Message NOT Sent: " + ex.Message);
Trace.WriteLine("!!! Message NOT Sent: " + ex.Message);
OnMessageSendingFailed();
}
}
private void OnMessageSendingFailed()
{
log.Debug("OnMessageSendingFailed");
if (MessageSendingFailed != null)
MessageSendingFailed(this, new EventArgs());
}
public void ReceiveMessage()
{
try
{
log.Debug(">>> ReceiveMessage");
if (this.fSocket != null && this.fSocket.Connected)
this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None
, new AsyncCallback(ReceiveCallback), this.fSocket);
else
{
log.Debug("Not Connected to Server");
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
OnMessageReceivingFailed();
}
}
private void OnMessageReceivingFailed()
{
log.Debug("OnMessageReceivingFailed");
if (MessageReceivingFailed != null)
MessageReceivingFailed(this, new EventArgs());
}
private void ReceiveCallback(IAsyncResult asyncResult)
{
string[] obj;
log.Debug("ReceiveCallback");
try
{
System.Net.Sockets.Socket socket = (System.Net.Sockets.Socket)asyncResult.AsyncState;
log.Debug("ReceiveCallback 2" + socket.ToString());
int read = socket.EndReceive(asyncResult);
if (read > 0)
{
currentmessage += Encoding.ASCII.GetString(this.readbuf, 0, read);
log.Debug("ReceiveCallback 3" + currentmessage);
char _charEOL = '\n';
if (currentmessage[currentmessage.Length - 1] != _charEOL)
{
this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None
, new AsyncCallback(ReceiveCallback), this.fSocket);
return;
}
readPacket(currentmessage.ToString());
obj = new string[] { "\n\n Server says :" + currentmessage };
currentmessage = "";
Buffer.SetByte(this.readbuf, 0, 0);
this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), this.fSocket);
}
if (read == 0 && !this.LocalsocketClientIsShutingDown)
{
this.fSocket.Close();
obj = new string[] { "Close Remote Socket" };
log.Debug("ReceiveCallback:Exception1-" + obj);
}
}
catch (SocketException ex)
{
obj = new string[1] { ex.Message };
log.Debug("ReceiveCallback:Exception2-" + ex.Message);
}
}
public void readPacket(string aMessage)
{
log.Debug("readPacket:"+aMessage);
try
{
string _formattedMsg = aMessage.Replace("\n", "");
string[] _tabAllMessages = _formattedMsg.Split(new char[] { '}' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i <= _tabAllMessages.Length - 1; i++)
{
_tabAllMessages[i] = _tabAllMessages[i] + "}";
//Trace.WriteLine("<<< Message Received: " + aMessage);
readSingleMessage(_tabAllMessages[i]);
}
}
finally
{
}
}
public abstract void readSingleMessage(string aMessage);//TO REDEFINE
public void Close()
{
log.Debug("SocketClient:Close");
try
{
if (this.fSocket != null && this.fSocket.Connected)
{
this.LocalsocketClientIsShutingDown = true;
//On ferme le socket
this.fSocket.Shutdown(SocketShutdown.Both);
System.Threading.Thread.Sleep(500);
//On détruit le socket
this.fSocket.Close();
Trace.WriteLine("Disconnected");
}
}
finally
{
}
}
The problem seems to come from that line in ConnectCallBack():
this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None
, new AsyncCallback(ReceiveCallback), this.fSocket);
I dont have any problem with that in a client application.
But when I use the socket in a windows service, it seems that if I keep that line, I will get a socket error a bit later.
If I dont keep the line, then both client and windows service wont be able to listen for some messages to read.
I m a bit lost as I used my windows application for a few month and never had an issue before I tried to turn it into a windows service.
Thanks!
EDIT: a few logs:
DEBUG2014-10-02 00:01:27 – Start Session
DEBUG2014-10-02 00:01:27 – Windows Service: Start Login
DEBUG2014-10-02 00:01:27 – ImgSocketClient:ConnectToServerAndSendPassword():xxxxxxxxx.com_23459
DEBUG2014-10-02 00:01:27 – SocketClient.ConnectToServer():xxxxxxxxx.com
DEBUG2014-10-02 00:01:27 – ConnectToServer()3: start BeginConnect()
DEBUG2014-10-02 00:01:27 – end BeginConnect with ConnectCallback()
DEBUG2014-10-02 00:01:27 – OnConnectionDone
DEBUG2014-10-02 00:01:28 – >>> Socket Connected - Sending Password
DEBUG2014-10-02 00:01:29 – >>> Sending Message: PASSWORD:xxx
DEBUG2014-10-02 00:01:29 – >>> Message Sent: 25 bytes
DEBUG2014-10-02 00:01:29 – ReceiveCallback
DEBUG2014-10-02 00:01:29 – **ReceiveCallback:Exception1-System.String[]**
DEBUG2014-10-02 00:01:29 – >>> Password Sent
DEBUG2014-10-02 00:01:29 – >>> Send Message to suscribe to updates
DEBUG2014-10-02 00:01:29 – >>> Sending Message: REQUEST:aaaaa
DEBUG2014-10-02 00:01:29 – Cant Send Message: REQUEST:aaaaa_ Not connected to socket
The problem is in lines:
if (read == 0 && !this.LocalsocketClientIsShutingDown)
{
this.fSocket.Close();
obj = new string[] { "Close Remote Socket" };
log.Debug("ReceiveCallback:Exception1-" + obj);
}
It is normal if You receive 0 bytes. Why did you close the socket in this case? After closing the socket you can't send the message "REQUEST:aaaaa"...
Remove these lines and try again.
In my client-server winform app,want to change ip address of client each time i run it.
A text box should take ip address of my client and then connect to server using local ip which is on same computer.
Client code:
public partial class Form1 : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public void ConnectToServer()
{
string server_localip = GetLocalIP();
clientSocket.Connect(server_localip, 8888);
}
public void SendData(string dataTosend)
{
if (string.IsNullOrEmpty(dataTosend))
return;
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = new byte[33];
outStream = System.Text.Encoding.ASCII.GetBytes(dataTosend);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
public void CloseConnection()
{
clientSocket.Close();
}
public string ReceiveData()
{
StringBuilder message = new StringBuilder();
serverStream = clientSocket.GetStream();
serverStream.ReadTimeout = 100;
//the loop should continue until no dataavailable to read and message string is filled.
//if data is not available and message is empty then the loop should continue, until
//data is available and message is filled.
while (true)
{
if (serverStream.DataAvailable)
{
int read = serverStream.ReadByte();
if (read > 0)
message.Append((char)read);
else
break;
}
else if (message.ToString().Length > 0)
break;
}
return message.ToString();
}
public string GetLocalIP()
{
IPHostEntry host;
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
return "127.0.0.1";
}
private void btnConnect_Click(object sender, EventArgs e)
{
ConnectToServer();
btnConnect.Text = "Connected";
}
private void btnRegister_Click(object sender, EventArgs e)
{
//if (!Regex.IsMatch(txtPrivateId.Text, #"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*"))
//{
// lblError.Text ="Please type a valid IMPI.";
//}
//if (!Regex.IsMatch(txtPublicId.Text, "[^0-9]"))
//{
// lblError.Text = lblError.Text + "\nPlease type a valid IMPU.";
//}
//else
//{
lblError.Text = "";
string data = txtPrivateId.Text + ";" + txtPublicId.Text;
for (int i = 0; i < 1; i++)
{
SendData(data);
}
string rec = null;
rec = ReceiveData();
txtReceive.Text = rec;
}
}
Any guidance would be appreciated..
you can use netsh to change your ip address:
netsh interface ip set address [adapter name] static [ip address] [subnet mask] [gateway] [interface metric]
try the code below:
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo("netsh", "interface ip set address \"Local Area Connection\" static 192.168.0.10 255.255.255.0 192.168.0.1 1");
p.StartInfo = psi;
p.Start();
and remember that your application should be running in elevated permissions.
"Local Area Connection" should match your adapter name
for more information about the netsh command line switches visit the Microsoft knowledge base article below:
http://support.microsoft.com/kb/242468