Здравствуйте! По какой причине программа может виснуть до получения ответа на string answer = ReceiveDataFromServer();? Т.е. пока не получит сокет в ответ. Если она не получает просто висит. Если получает - то поломанная кодировка.
namespace HotKeyTest
{
public partial class Form1 : Form
{
// Receiving byte array
byte[] bytes = new byte[1024];
Socket senderSock;
public Form1()
{
InitializeComponent();
Boolean success = Form1.RegisterHotKey(this.Handle, this.GetType().GetHashCode(), 0x0002, 0x4c);//Set hotkey as 'ctrl+l'
}
private void button1_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader("settings");
IPAddress ip = IPAddress.Parse(sr.ReadLine());
Connect(ip);
sr.Close();
Thread.Sleep(2000);
Sendswitch();
Disconnect();
}
private void Connect(IPAddress ip)
{
try
{
// Create one SocketPermission for socket access restrictions
SocketPermission permission = new SocketPermission(
NetworkAccess.Connect, // Connection permission
TransportType.Tcp, // Defines transport types
"", // Gets the IP addresses
SocketPermission.AllPorts // All ports
);
// Ensures the code to have permission to access a Socket
permission.Demand();
// Resolves a host name to an IPHostEntry instance
IPHostEntry ipHost = Dns.GetHostEntry("");
// Gets first IP address associated with a localhost
IPAddress ipAddr = ip;
// Creates a network endpoint
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 55443);
// Create one Socket object to setup Tcp connection
senderSock = new Socket(
ipAddr.AddressFamily,// Specifies the addressing scheme
SocketType.Stream, // The type of socket
ProtocolType.Tcp // Specifies the protocols
);
senderSock.NoDelay = false; // Using the Nagle algorithm
// Establishes a connection to a remote host
senderSock.Connect(ipEndPoint);
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
private void Sendswitch()
{
try
{
// Sending message
//<Client Quit> is the sign for end of data
byte[] msg = Encoding.Unicode.GetBytes("{\"id\":1,\"method\":\"get_prop\",\"params\":[\"power\", \"not_exist\", \"bright\"]}");
// Sends data to a connected Socket.
int bytesSend = senderSock.Send(msg);
Thread.Sleep(2000);
string answer = ReceiveDataFromServer();
MessageBox.Show(answer);
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
private string ReceiveDataFromServer()
{
try
{
// Receives data from a bound Socket.
int bytesRec = senderSock.Receive(bytes);
// Converts byte array to string
String theMessageToReceive = Encoding.Unicode.GetString(bytes, 0, bytesRec);
// Continues to read the data till data isn't available
while (senderSock.Available > 0)
{
bytesRec = senderSock.Receive(bytes);
theMessageToReceive += Encoding.Unicode.GetString(bytes, 0, bytesRec);
}
return theMessageToReceive;
}
catch (Exception exc) { return exc.ToString(); }
}
private void Disconnect()
{
try
{
// Disables sends and receives on a Socket.
senderSock.Shutdown(SocketShutdown.Both);
//Closes the Socket connection and releases all resources
senderSock.Close();
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
}
}
Раделим вопрос на две части - блокировка и испорченные данные.
согласно документации - https://msdn.microsoft.com/ru-ru/library/8s4y8aff(v=vs.110).aspx - вызов Receive блокирующий. То есть, он возвратит данные как только в сокете будет хоть один байт. Так как там есть цикл, то там будет блокирование, пока с той стороны не закроют сокет (то есть, даже если все данные прибегут, то код все равно будет ждать закрытия сокета. Если сервер не закрывает сокет сразу, это может быть причиной подвисания.)
Теперь о испорченных данных. Метод Receive устроен так, что он будет возвращать данные произвольными порциями от 1 байта до ..., а тут спорный вопрос, возможно несколько килобайт (верю в 8килобайт), а может и сотни (я не достаточно хорошо знаю подсистему .NET). Но это не имеет значения. Важно то, что если с одной стороны отправлять порциями по 100 байт, то с другой стороны не объязательно будет читаться по 100 байт. может и по 20, 40 и другими.
А это важно, так как юникодная строка (какая она бы не была, utf-8 или ucs-16) не объязательно содержит один байт на символ и строка может разбиваться по средине символа. И вот тут будут проблемы. Но эту проблему легко решить - нужно прочитать все данные и только потом декодировать.
А вот с первой проблемой немного сложнее. Нужно знать "структуру данных". Например, данные могут читаться до перевода строк или размер данных известен.
ЗдравствуйтеЕсть сайт, написанный с использованием синтаксиса Razor
Ситуация такая, собираюсь сделать админ панель для создания объектов: новых и редактирования старых, админ будет только один, то есть я не собираюсь...