В настоящее время программа работает: вы вводите IP-адрес, нажимаете «Подключиться», вводите сообщение, нажимаете «Отправить», и сервер получает и отображает сообщение.
Код клиента:
public class Client
{
private const int DataSize = 65635;
private byte[] data = new byte[DataSize];
public Socket _socket; //the main socket
public string strMsg; //sender's message string
{
get
{
IPHostEntry ipHostInfo = Dns.GetHostEntry("localhost");
IPAddress ipAddress = ipHostInfo.AddressList[1];
return ipAddress.ToString();
}
}
public EndPoint _epHost;
public bool Connect(string address)
{
bool result = false;
if (string.IsNullOrEmpty(address)) return false;
try
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse(address);
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8040);
_epHost = (EndPoint)ipEndPoint;
_socket.Connect(_epHost);
result = true;
}
catch (SocketException ex)
{
throw new Exception(ex.Message);
}
return result;
}
// CITATION: Send() is a modified form of code by Jan Slama on his website
// Link: http://www.csharp-examples.net/socket-send-receive/
// License: "simple, straightforward examples suitable for copy and paste"
public void Send(Data mailToBeSent, int offset, int timeout)
{
int startTickCount = Environment.TickCount;
int sent = 0; // how many bytes is already sent
data = mailToBeSent.ToByte();
do
{
if (Environment.TickCount > startTickCount + timeout)
{
data = null;
throw new Exception("Timeout.");
}
try
{
sent += _socket.Send(data, offset + sent,
data.Length - sent, SocketFlags.None);
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.WouldBlock ||
ex.SocketErrorCode == SocketError.IOPending ||
ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
// socket buffer is probably full, wait and try again
Thread.Sleep(30);
else
throw ex; // any serious error occurs
}
}
while (sent < data.Length);
}
public void Close()
{
if (_socket != null)
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
}
}
public enum Command //Commands for sender/receiver
{
Message, //Send a text message to the receiver
Close, //Close
Null, //No command
}
}
Я пытаюсь изменить его, чтобы, если сервер/получатель временно отключился, когда клиент/отправитель отправляет ему сообщение, отправитель автоматически подождет десять секунд, затем попытается повторно подключиться и повторно отправить сообщение.
Прямо сейчас я могу сделать это, подождав вручную, затем повторно щелкнув «подключиться», а затем «отправить», но я бы хотел, чтобы отправитель справился с этим самостоятельно.
Код формы:
public partial class Form1 : Form
{
private Client _client;
public Form1()
{
InitializeComponent();
_client = new Client();
Text = string.Format("Address: {0}", _client.IpAddress);
btnDisconnect.Enabled = false;
tbMsg.Enabled = false;
btnSend.Enabled = false;
}
private void btnConnect_Click(object sender, EventArgs e)
{
if (_client.Connect(tbAddress.Text))
{
btnDisconnect.Enabled = true;
tbMsg.Enabled = true;
btnSend.Enabled = true;
tsLabel.Text = "Online";
}
}
private void btnSend_Click(object sender, EventArgs e)
{
try
{
Data mailToBeSent = new Data();
mailToBeSent.cmdCommand = Command.Message;
mailToBeSent.ipAddress = _client.IpAddress;
mailToBeSent.strMessage = tbMsg.Text;
_client.Send(mailToBeSent, 0, 1000);
tbMsg.Text = string.Empty;
}
catch (Exception)
{
MessageBox.Show("Unable to deliver mail to receiver.", "Client",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
Data mailToBeSent = new Data();
mailToBeSent.cmdCommand = Command.Close;
mailToBeSent.ipAddress = _client.IpAddress;
mailToBeSent.strMessage = string.Empty;
_client.Send(mailToBeSent, 0, 1000);
_client.Close();
}
}
Пишу сюда первый раз, надеюсь правильно сделал. Любые советы приветствуются.