C# and Android Socket image sending - c#

i'm trying to do a new application for android. I connected my C# app with Android app by sockets and i can send texts easily. However, the point i couldn't do is sending pictures. Client Android app will send a text and my desktop app will answer with a bitmap image. I tried Base64 coding but it's not working for me. I'm stuck.
C# server response code;
else if(text.ToLower() == "resim")
{
response = "resim gönderiliyor...";
byte[] text_ = Encoding.UTF8.GetBytes(response);
socket.BeginSend(text_, 0, text_.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
Thread.Sleep(3000);
byte[] buffer = ToBase64String(ScreenCaptured(), ImageFormat.Bmp);
socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
}
ToBase64String function;
public string ToBase64String(Bitmap bmp, ImageFormat imageFormat)
{
string base64String = string.Empty;
MemoryStream memoryStream = new MemoryStream();
bmp.Save(memoryStream, imageFormat);
memoryStream.Position = 0;
byte[] byteBuffer = memoryStream.ToArray();
memoryStream.Close();
base64String = Convert.ToBase64String(byteBuffer);
byteBuffer = null;
return base64String;
}
Android Client Side;
public void addListener(OnListener listener) {
this.listener = listener;
}
static Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (flag) {
bmp = SixtyFourBaseToBitmap(msg.obj.toString());
if(bmp != null)
{
imgView.setImageBitmap(bmp);
}
else
{
kq += msg.obj.toString() + "\r\n";
textResponse.setText(kq);
}
}
}
};
public static Bitmap SixtyFourBaseToBitmap(String codedString)
{
try
{
byte[] decodedString = Base64.decode(codedString, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
return decodedByte;
}
catch (Exception e)
{
return null;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonConnect = (ImageButton) findViewById(R.id.connect_button);
settings_button_ = (ImageButton) findViewById(R.id.settings_button);
textResponse = (TextView) findViewById(R.id.response);
imgView = (ImageView) findViewById(R.id.response_img);
preferences= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
editor = preferences.edit();
ipbilgisi=preferences.getString("ip", "IP Girin");
portBilgisi= preferences.getString("port", "Port Girin");
buttonConnect.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
myClientTask = new ClientTask(ipbilgisi, portBilgisi);
myClientTask.execute();
}
});
}
public void goSettings(View v)
{
Intent i = new Intent(this, Settings.class);
startActivity(i);
finish();
}
public class ClientTask extends AsyncTask<String, String, String> implements
OnListener {
String dstAddress;
int dstPort;
PrintWriter out1;
ClientTask(String addr, String port) {
dstAddress = addr;
dstPort = Integer.parseInt(port);
}
#Override
protected void onProgressUpdate(String... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
socket = new Socket(dstAddress, dstPort);
out1 = new PrintWriter(socket.getOutputStream(), true);
//out1.print("Hello server!");
out1.flush();
BufferedReader in1 = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
do {
try {
if (!in1.ready()) {
if (message != null) {
MainActivity.handler.obtainMessage(0, 0, -1,
"Server: " + message).sendToTarget();
message = "";
}
}
int num = in1.read();
message += Character.toString((char) num);
} catch (Exception classNot) {
}
} while (!message.equals("bye"));
try {
sendMessage("bye");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
try {
if (socket.isClosed()) {
flag = false;
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Bağlantı Hatası!", Toast.LENGTH_LONG).show();
}
super.onPostExecute(result);
}
#Override
public void listener(String text) {
// TODO Auto-generated method stub
sendMessage(text);
}
void sendMessage(String msg) {
try {
out1.print(msg);
out1.flush();
if (!msg.equals("bye"))
MainActivity.handler.obtainMessage(0, 0, -1, "Me: " + msg)
.sendToTarget();
else
MainActivity.handler.obtainMessage(0, 0, -1,
"Ngắt kết nối!").sendToTarget();
} catch (Exception ioException) {
ioException.printStackTrace();
}
}
}
public void send(View v) {
addListener(myClientTask);
if (listener != null)
listener.listener(((EditText) findViewById(R.id.editText1))
.getText().toString());
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
try {
if (listener != null)
listener.listener("bye");
socket.close();
} catch (Exception e) {
// TODO: handle exception
}
super.onDestroy();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
try {
if (listener != null)
listener.listener("bye");
socket.close();
} catch (Exception e) {
// TODO: handle exception
}
super.onStop();
}
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
}
Your help is appreciated.
Best regards.

Related

How to show a result from an async task in GUI label?

I create client application for read message from server. The client application has class SocketClient which has function ReadDataAsync() for read message from server like this.
namespace SocketAsync
{
public class SocketClient
{
IPAddress mServerIPAddress;
int mServerPort;
TcpClient mClient;
public SocketClient()
{
mClient = null;
mServerPort = -1;
mServerIPAddress = null;
}
public IPAddress ServerIPAddress
{
get
{
return mServerIPAddress;
}
}
public int ServerPort
{
get
{
return mServerPort;
}
}
public bool SetServerIPAddress(string _IPAddressServer)
{
IPAddress ipaddr = null;
if (!IPAddress.TryParse(_IPAddressServer, out ipaddr))
{
Debug.WriteLine("Invalid server IP supplied.");
return false;
}
mServerIPAddress = ipaddr;
return true;
}
public bool SetPortNumber(string _ServerPort)
{
int portNumber = 0;
if (!int.TryParse(_ServerPort.Trim(), out portNumber))
{
Debug.WriteLine("Invalid port number supplied, return.");
return false;
}
if (portNumber <= 0 || portNumber > 65535)
{
Debug.WriteLine("Port number must be between 0 and 65535.");
return false;
}
mServerPort = portNumber;
return true;
}
public async Task ConnectToServer()
{
if (mClient == null)
{
mClient = new TcpClient();
}
try
{
await mClient.ConnectAsync(mServerIPAddress, mServerPort);
Debug.WriteLine(
string.Format("Connected to server IP/Port: {0} / {1}",
mServerIPAddress, mServerPort));
ReadDataAsync(mClient);
}
catch (Exception excp)
{
Console.WriteLine(excp.ToString());
throw;
}
}
private async Task ReadDataAsync(TcpClient mClient)
{
try
{
StreamReader clientStreamReader = new StreamReader(mClient.GetStream());
char[] buff = new char[64];
int readByteCount = 0;
while (true)
{
readByteCount = await clientStreamReader.ReadAsync(buff, 0, buff.Length);
if (readByteCount <= 0)
{
Debug.WriteLine("Disconnected from server.");
mClient.Close();
break;
}
Debug.WriteLine(
string.Format("Received bytes: {0} - Message: {1}",
readByteCount, new string(buff)));
Array.Clear(buff, 0, buff.Length);
}
}
catch (Exception excp)
{
Console.WriteLine(excp.ToString());
throw;
}
}
}
}
ReadDataAsync() can show message in output but I want to show message in Form1. So I put the label1 in Form. I connect to server when click button1 like this.
namespace TestClient
{
public partial class Form1 : Form
{
SocketClient client = new SocketClient();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if(!client.SetServerIPAddress("127.0.0.1")||
!client.SetPortNumber("23000"))
{
Debug.WriteLine("Wrong IP Address or port");
return;
}
client.ConnectToServer();
string strInputUser = null;
}
Can I show message in ReadDataAsync() to Form1. How to do that?
Use events.
Create your own EventArgs to transport the messages:
public class MessageEventArgs : EventArgs
{
public string Message { get; private set; }
public MessageEventArgs(string message)
{
this.Message = message;
}
}
In your SocketClient class declare the event:
namespace SocketAsync
{
public class SocketClient
{
IPAddress mServerIPAddress;
int mServerPort;
TcpClient mClient;
public event EventHandler<MessageEventArgs> Message;
// your other code
}
}
Also in your SocketClient class, use (raise) the event in ReadDataAsync():
private async Task ReadDataAsync(TcpClient mClient)
{
try
{
StreamReader clientStreamReader = new StreamReader(mClient.GetStream());
char[] buff = new char[64];
int readByteCount = 0;
while (true)
{
readByteCount = await clientStreamReader.ReadAsync(buff, 0, buff.Length);
if (readByteCount <= 0)
{
Message?.Invoke(this, new MessageEventArgs("Disconnected from server."));
Debug.WriteLine("Disconnected from server.");
mClient.Close();
break;
}
Message?.Invoke(this, new MessageEventArgs(string.Format("Received bytes: {0} - Message: {1}",
readByteCount, new string(buff))));
Debug.WriteLine(
string.Format("Received bytes: {0} - Message: {1}",
readByteCount, new string(buff)));
Array.Clear(buff, 0, buff.Length);
}
}
catch (Exception excp)
{
Console.WriteLine(excp.ToString());
throw;
}
}
Finally, in your form, consume the event:
namespace TestClient
{
public partial class Form1 : Form
{
SocketClient client = new SocketClient();
public Form1()
{
InitializeComponent();
client.Message += Client_Message;
}
private void Client_Message(object sender, MessageEventArgs e)
{
label1.Invoke(new Action() => label1.Text = e.Message);
}
// your other code
}
}

Send Audio Stream from Android(Client) to C#(Server) using Websocket

I am trying to send audio stream/wav file as a byte array from android to C# server, but not able to receive it properly, though I am able to receive a simple String.
C# server disconnects after few seconds, with protocol error as reason
protocol error: Code = 1002, I think when the file is large the frame size exceeds and web socket connection is lost. Is there a way out?
I also tried sending a wav file as byte array from android as following, removing the recording stream:
byte[] buffer = new byte[1024];
try {
FileInputStream fis = new FileInputStream(file);
while(true) {
int in = fis.read(buffer, 0, buffer.length);
if(in != -1) {
mWebSocket.send(buffer);
}else{
break;
}
}
}catch (Exception e) {
Log.d("Exception", e.toString());
}
Android Code:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button stopPlaying, send, record, stop;
private AudioRecord audiorecord;
private static int SAMPLER = 44100; //Sample Audio Rate
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufSize = AudioRecord.getMinBufferSize(SAMPLER, channelConfig, audioFormat);
private boolean status = true;
URI uri = URI.create("ws://ab1d04d2.ngrok.io");
private String outputFile = null;
private Thread senderThread = null;
private WebSocketClient mWebSocket;
private File file = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
file = new File(Environment.getExternalStorageDirectory(), "recording.wav");
setContentView(honeywell.rana.sumit.voicecontrol.R.layout.activity_main);
audiorecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLER, channelConfig, audioFormat, minBufSize);
send = (Button) findViewById(R.id.send);
send.setOnClickListener(this);
stop = (Button) findViewById(R.id.stop);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.send:
AudioTask task = new AudioTask();
task.execute();
break;
case R.id.stop:
audiorecord.stop();
mWebSocket.close();
Log.d("Socket Closed", "");
default:
break;
}
}
public class AudioTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
mWebSocket = new WebSocketClient(uri) {
#Override
public void onOpen(ServerHandshake handshakedata) {
Log.d("Connected: ", mWebSocket.getConnection().toString());
mWebSocket.send("hello!");
byte[] buffer = new byte[minBufSize];
audiorecord.startRecording();
while (true) {
int number = audiorecord.read(buffer, 0, minBufSize);
for (int i = 0; i < number; i++) {
mWebSocket.send(buffer);
}
}
}
#Override
public void onMessage(String message) {
Log.d("Received: ", message);
}
#Override
public void onClose(int code, String reason, boolean remote) {
Log.d("Closed", "Code = " + code + ", Reason: " + reason);
}
#Override
public void onError(Exception ex) {
Log.d("Error: ", ex.toString());
}
};
mWebSocket.connect();
} catch (Exception e) {
Log.d("Exception: ", e.toString());
}
return null;
}
}
}
C# Code:
namespace ChatServer
{
class Program
{
static WaveOut waveOut;
static BufferedWaveProvider bufferedWaveProvider = null;
private static WebSocketServer appServer = new WebSocketServer();
static void Main(string[] args)
{
Console.WriteLine("Press any key to start the WebSocketServer!");
Console.ReadKey();
Console.WriteLine();
waveOut = new WaveOut();
bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(44100, 16, 2));
waveOut.Init(bufferedWaveProvider);
waveOut.Play();
appServer.NewMessageReceived += new SessionHandler<WebSocketSession, string>(appServer_NewMessageReceived);
appServer.NewDataReceived += new SessionHandler<WebSocketSession, byte[]>(appServer_NewDataReceived);
appServer.NewSessionConnected += AppServer_NewSessionConnected;
appServer.SessionClosed += new SessionHandler<WebSocketSession, CloseReason>(appServer_SessionClosed);
//Setup the appServer
if (!appServer.Setup(80)) //Setup with listening port
{
Console.WriteLine("Failed to setup!");
Console.ReadKey();
return;
}
//Try to start the appServer
if (!appServer.Start())
{
Console.WriteLine("Failed to start!");
Console.ReadKey();
return;
}
Console.WriteLine("The server started successfully, press key 'q' to stop it!");
while (Console.ReadKey().KeyChar != 'q')
{
Console.WriteLine();
continue;
}
//Stop the appServer
appServer.Stop();
Console.WriteLine();
Console.WriteLine("The server was stopped!");
Console.ReadKey();
}
private static void AppServer_NewSessionConnected(WebSocketSession session)
{
Console.WriteLine("New Client connected: " + session.SessionID);
}
static void appServer_SessionClosed(WebSocketSession session, CloseReason reason)
{
Console.WriteLine(reason);
}
static void appServer_NewDataReceived(WebSocketSession session, byte[] value)
{
bufferedWaveProvider.AddSamples(value, 0, value.Length);
}
static void appServer_NewMessageReceived(WebSocketSession session, string message)
{
//Send the received message back
session.Send("Server: " + message);
Console.WriteLine(message);
}
I got it working finally, it was just a minute problem. I just reduced the buffer size in android to 64/128/512 and now it's working perfectly.

Android socket connection with a server

I'm trying to connect my Android phone with a Server. On the Server runs a program written in C#. I've tryed to make it with the following code but it doesn't work.
This is the Android code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Socket socket;
int port = 52301;
String ip = "79.16.115.30";
Button b = (Button) findViewById(R.id.myButton);
assert b != null;
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
byte[] b = ip.getBytes();
/*SocketAddress socketAddress = new InetSocketAddress(ip, port);
socket.connect(socketAddress);*/
socket = new Socket(ip, port);
Toast.makeText(v.getContext(), "CONNESSO", Toast.LENGTH_SHORT).show();
} catch (UnknownHostException e) {
Toast.makeText(v.getContext(), "CHI MINCHIA è COSTUI", Toast.LENGTH_SHORT).show();
}catch(IOException e) {
Toast.makeText(v.getContext(), "NO I/O", Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
String cause = "Message: " + e.getMessage();
Toast.makeText(v.getContext(), cause, Toast.LENGTH_SHORT).show();
}
}
});
}
I've tryed also to use the code commented but it doesn't work;
This is the program that runs on the Server:
static void Main(string[] args)
{
string ip = Get_external_ip();
int port = 52301;
int max = 10;
IPAddress ipAddress = IPAddress.Parse("192.168.1.56");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port); //setto i parametri del socket
Socket sockServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //creo il socket
Socket client;
Console.WriteLine(ip);
try
{
sockServer.Bind(localEndPoint);
sockServer.Listen(max);
while (true)
{
client = sockServer.Accept();
Console.WriteLine(client.RemoteEndPoint.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
private static string Get_external_ip()
{
try
{
WebClient client = new WebClient();
return client.DownloadString("http://icanhazip.com/").TrimEnd('\r', '\n');
}
catch (Exception e)
{
return e.Message;
}
}
First of all, use background Thread for network.
I will give you my working snippet. Try to apply it for your needs.
public class YourClass {
//Server socket variables
private ServerSocket serverSocket;
private DataOutputStream dataOutputStream;
private DataInputStream dataInputStream;
private Socket client;
....
private class SocketServerThread extends Thread {
private int port;
private SocketServerThread(int port) {
this.port = port;
}
#Override
public void run() {
dataInputStream = null;
dataOutputStream = null;
try {
serverSocket = new ServerSocket(port);
isSockedOpened = true;
client = serverSocket.accept(); //wait for client
isClientConnected = true;
Log.d(TAG, "Client connected: " + client.getInetAddress().getHostAddress());
dataInputStream = new DataInputStream(
client.getInputStream());
dataOutputStream = new DataOutputStream(
client.getOutputStream());
String messageFromClient;
while (isClientConnected) {
messageFromClient = dataInputStream.readLine();
handleIncomingMessage(messageFromClient);
}
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (NullPointerException e) {
Log.e(TAG, e.getMessage());
}
}
}
To open connection:
public void connect(int port) {
this.port = port;
Thread socketServerThread = new Thread(new SocketServerThread(port));
socketServerThread.start();
}
That's how you check if client connected;
public boolean isConnected() {
return serverSocket.isBound() || client.isConnected();
}
To disconnect:
public void disconnect(boolean needsGathering) {
if (isSockedOpened) {
try {
if (serverSocket != null) {
serverSocket.close();
}
if (dataOutputStream != null) {
dataOutputStream.close();
}
if (dataInputStream != null) {
dataInputStream.close();
}
if (client != null) {
client.close();
}
} catch (IOException e) {
Log.e(TAG, "Couldn't get I/O for the connection");
Log.e(TAG, e.getMessage());
}
} else {
Log.d(TAG, "Socket was not opened");
}
}
}

Android Video Streaming Using DatagramSocket setPreviewCallback

I've made an application that obeys UDP using Datagram Socket in android. I'm trying to use Camera's setPreviewCallback function to send bytes to a (c#) client, using Datagram Socket;
But,
The problem is : it throws an exception "The datagram was too big to fit the specified buffer,so truncated" and no bytes are received on client.
I've changed the size of buffer to different values but none work. Now :
Is Datagram approach is right?
What alternatives/approach I'd use to achieve the task?
What's the ideal solution for this?
Android Server :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoView = (VideoView) findViewById(R.id.videoView1);
start = (Button)findViewById(R.id.start);
stop = (Button)findViewById(R.id.stop);
setTitle(GetCurrentIP());
mainList = new LinkedList<byte[]>();
secondaryList = new LinkedList<byte[]>();
mCam = null;
mCam = Camera.open();
if (mCam == null) {
Msg("Camera is null");
} else {
if (!Bind()) {
Msg("Bind Error.");
} else {
Msg("Bound Success.");
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
mCam.setPreviewDisplay(videoView.getHolder());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
Msg(e1.getMessage());
}
mCam.setPreviewCallback(new PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
DatagramPacket pack;
try {
pack = new DatagramPacket(data, data.length, InetAddress.getByName(clientIP), clientPort);
me.send(pack);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Msg(e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Msg(e.getMessage());
}
}
});
mCam.startPreview();
}
});
}
}
}
private boolean Bind(){
try {
me = new DatagramSocket(MY_PORT);
return true;
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Msg(e.getMessage());
}
return false;
}
private String GetCurrentIP(){
WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
return Formatter.formatIpAddress(wifiMgr.getConnectionInfo().getIpAddress());
}
public void Msg(String msg){
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
Log.v(">>>>>", msg);
}
}
C# client :
public partial class Form1 : Form
{
const int MY_PORT = 55566;
IPAddress MY_IP;
Thread Receiver;
Socket me;
EndPoint myEndPoint;
EndPoint serverEndPoint;
byte[] buffer;
public Form1()
{
InitializeComponent();
}
private IPAddress GetCurrentIPAddress()
{
IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
var selectedIPs = from ip in ips
where ip.AddressFamily == AddressFamily.InterNetwork
select ip;
return selectedIPs.First();
}
private bool Bind()
{
try
{
myEndPoint = new IPEndPoint(MY_IP, MY_PORT);
me.Bind(myEndPoint);
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return false;
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
MY_IP = GetCurrentIPAddress();
this.Text = MY_IP.ToString()+":"+MY_PORT;
me = new Socket
(
AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp
);
if (!Bind())
Task.Run(()=> MessageBox.Show("Bind() error."));
else
Task.Run(() => MessageBox.Show("Bind success."));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//private void AddToListBox(String msg)
//{
// this.Invoke((Action)delegate() { this.listBox1.Items.Add((this.listBox1.Items.Count+1)+" : "+msg); });
//}
private void buttonStart_Click(object sender, EventArgs e)
{
serverEndPoint = new IPEndPoint(IPAddress.Parse(textBoxmyIP.Text), int.Parse(textBoxmyPort.Text));
Receiver = new Thread(new ThreadStart(Receive));
Receiver.Start();
}
private Image ByteToImage(byte[] bytes)
{
MemoryStream ms = new MemoryStream(bytes);
return Image.FromStream(ms);
}
private void Receive()
{
while (true)
{
buffer = new byte[100];
int nobs = me.ReceiveFrom(buffer, ref serverEndPoint);
if (nobs>0)
{
Task.Run(() => MessageBox.Show("Bytes received"));
//AddToListBox(Encoding.Default.GetString(buffer));
//AddToPictureBox(buffer);
}
Thread.Sleep(100);
}
}
private void AddToPictureBox(byte[] buffer)
{
this.BeginInvoke
(
(Action)
delegate()
{
pictureBox1.Image = ByteToImage(buffer);
}
);
}
}

C# Form. Changing a Client / Server chat room so clients can speak with one another

This question has probably been asked before.
Okay so I am still learning how to program with sockets but I was wondering how you could change the client / server so that clients can talk amongst themselves as well as the server talking to the clients like an administrator.
I have found various things on Handle Clients but these were for Console Apps and not C# Windows Forms, I tried to covert them but with no luck.
This is my server code so far.
namespace Socket_Server
{
public partial class Form1 : Form
{
const int MAX_CLIENTS = 30;
public AsyncCallback pfnWorkerCallBack;
private Socket m_mainSocket;
private Socket[] m_workerSocket = new Socket[30];
private int m_clientCount = 20;
string readData = null;
public Form1()
{
InitializeComponent();
textBoxIP.Text = GetIP();
}
private void buttonStartListen_Click(object sender, EventArgs e)
{
try
{
if (textBoxPort.Text == "")
{
MessageBox.Show("Please enter a Port Number");
return;
}
string portStr = textBoxPort.Text;
int port = System.Convert.ToInt32(portStr);.
m_mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);
m_mainSocket.Bind(ipLocal);
m_mainSocket.Listen(4);
m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
UpdateControls(true);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
private void UpdateControls(bool listening)
{
buttonStartListen.Enabled = !listening;
buttonStopListen.Enabled = listening;
}
public void OnClientConnect(IAsyncResult asyn)
{
try
{
m_workerSocket[m_clientCount] = m_mainSocket.EndAccept(asyn);
WaitForData(m_workerSocket[m_clientCount]);
++m_clientCount;
String str = String.Format("Client # {0} connected", m_clientCount);
Invoke(new Action(() =>textBoxMsg.Clear()));
Invoke(new Action(() =>textBoxMsg.AppendText(str)));
m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
catch (ObjectDisposedException)
{
System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
public class SocketPacket
{
public System.Net.Sockets.Socket m_currentSocket;
public byte[] dataBuffer = new byte[1024];
}
public void WaitForData(System.Net.Sockets.Socket soc)
{
try
{
if (pfnWorkerCallBack == null)
{
pfnWorkerCallBack = new AsyncCallback(OnDataReceived);
}
SocketPacket theSocPkt = new SocketPacket();
theSocPkt.m_currentSocket = soc;// could be this one!!!
soc.BeginReceive(theSocPkt.dataBuffer, 0,
theSocPkt.dataBuffer.Length,
SocketFlags.None,
pfnWorkerCallBack,
theSocPkt);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
public void OnDataReceived(IAsyncResult asyn)
{
try
{
SocketPacket socketData = (SocketPacket)asyn.AsyncState;
int iRx = 0;
iRx = socketData.m_currentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(socketData.dataBuffer,
0, iRx, chars, 0);
System.String szData = new System.String(chars);
Invoke(new Action(() => richTextBoxSendMsg.AppendText(szData)));
Invoke(new Action(() => richTextBoxSendMsg.AppendText(Environment.NewLine)));
WaitForData(socketData.m_currentSocket);
}
catch (ObjectDisposedException)
{
System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
private void buttonSendMsg_Click(object sender, EventArgs e)
{
try
{
Object objData = txtBoxType.Text;
byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString());
for (int i = 0; i < m_clientCount; i++)
{
if (m_workerSocket[i] != null)
{
if (m_workerSocket[i].Connected)
{
m_workerSocket[i].Send(byData);
txtBoxType.Clear();
}
}
}
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
private void buttonStopListen_Click(object sender, EventArgs e)
{
CloseSockets();
UpdateControls(false);
}
String GetIP()
{
String strHostName = Dns.GetHostName();
IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);
String IPStr = "";
foreach (IPAddress ipaddress in iphostentry.AddressList)
{
if (ipaddress.IsIPv6LinkLocal == false)
{
IPStr = IPStr + ipaddress.ToString();
return IPStr;
}
}
return IPStr;
}
private void buttonClose_Click(object sender, EventArgs e)
{
CloseSockets();
Close();
}
void CloseSockets()
{
if (m_mainSocket != null)
{
m_mainSocket.Close();
}
for (int i = 0; i < m_clientCount; i++)
{
if (m_workerSocket[i] != null)
{
m_workerSocket[i].Close();
m_workerSocket[i] = null;
}
}
}
}
}
Thank you in advance.

Categories