Hello ,
Please bear in mind that im not an experts, and my knowledge hardly exceeds what google search results has to offer a noob.
i have a multi-client server application, for video conferencing, and everything works good untill more than 4 or 5 users connects to the server.
I know i should be using UDP, not TCP, but this is the way i did it, and i want you to take a look at it and tell me what you think.
Client Connection Code
VideoSoc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
int Videoport = 8003;
IPAddress server_ip = IPAddress.Parse(textBox1.Text);
IPEndPoint ConnEndPoint = new IPEndPoint(server_ip, Videoport);
VideoSoc.Connect(ConnEndPoint);
// i dont remember why i used these numbers, but i think they //solved a problem and now im afraid to change them :)
VideoSoc.SendTimeout = 2000;
WaitForVideoSoc(VideoSoc, 99999);
Server Accept Connection Code
public void onVideoReceived(IAsyncResult asyn)
{
SocketsPackets.Video_SockPacket VideoPacket = (SocketsPackets.Video_SockPacket)asyn.AsyncState;
try
{
CheckForIllegalCrossThreadCalls = false;
int iRx = 0;
iRx = VideoPacket.m_CurrentVideo_Sock.EndReceive(asyn);
char[] chars = new char[32];
Decoder d = Encoding.UTF8.GetDecoder();
int charlen = d.GetChars(VideoPacket.Videobuffer, 0, 32, chars, 0);
string szData = new String(chars);
List<byte> bl = new List<byte>(VideoPacket.Videobuffer);
bl.RemoveRange(iRx, VideoPacket.Videobuffer.Length - iRx);
byte[] nb = new byte[bl.Count];
bl.CopyTo(nb);
//here i add the received video data (which is a jpg image) and i add it to a datalist for that user, then i start a thread to check if there is any data and i send it to all other connected users. see code below
Rooms[VideoPacket.Index].UsersList[VideoPacket.Pos].VideoList.AddRange(nb);
bl.Clear();
I use a timer to check if there are any stored data available in the list for sending
private void ProcessVideoData_timer_Tick(object sender, EventArgs e)
{
try
{
for (int i = 0; i < Rooms.Count; i++)
{
// if the previouse processing operation is done.. create a new thread to process the video data..
if (Rooms[i].DoneProcessing)
{
Rooms[i].DoneProcessing = false;
Thread video_thread = new Thread(ProcessVideoSending);
video_thread.Start(i);
}
}
}
catch (Exception ex)
{
logerror(ex);
}
}
here is the code the process the data and send it.
public void ProcessVideoSending(object Roomindex)
{
// get the room index
int roomindex = (int)Roomindex;
Rooms[roomindex].DoneProcessing = false;
countt++;
// textBox1.Text = countt.ToString();
try
{
for (int x = 0; x < Rooms[roomindex].UsersList.Count; x++)
{
try
{
// for reasons unknown to me, sometimes the videolist.count is less than zero. example -2998 and .clear() does onthing
if (Rooms[roomindex].UsersList[x].VideoList.Count < 0)
{
Rooms[roomindex].UsersList[x].VideoList = new List<byte>();
//break;
}
// 9 is the number of the identifiers..
while (Rooms[roomindex].UsersList[x].VideoList.Count > 9)
{
// if this happens.. its a video jam... clear it..
if (Rooms[roomindex].UsersList[x].VideoList.Count > 200000)
Rooms[roomindex].UsersList[x].VideoList.Clear();
// get the chunk lengt.. some pictures are sent in chunks to reduce the network load
string chunklength = "0";
try
{
chunklength =
Rooms[roomindex].UsersList[x].VideoList[6].ToString() +
Rooms[roomindex].UsersList[x].VideoList[7].ToString() +
Rooms[roomindex].UsersList[x].VideoList[8].ToString() +
Rooms[roomindex].UsersList[x].VideoList[9].ToString() +
Rooms[roomindex].UsersList[x].VideoList[10].ToString();
}
catch (Exception exp)
{
Rooms[roomindex].UsersList[x].VideoList.Clear();
break;
}
int chunklen = int.Parse(chunklength);
// reassemble the picture.. and send it to all users.
if (chunklen <= Rooms[roomindex].UsersList[x].VideoList.Count && chunklen != 0)
{
byte[] videodata = new byte[chunklen];
Rooms[roomindex].UsersList[x].VideoList.CopyTo(0, videodata, 0, chunklen);
Rooms[roomindex].UsersList[x].VideoList.RemoveRange(0, chunklen);
for (int i = 0; i < Rooms[roomindex].UsersList.Count; i++)
{
if (i != x && Rooms[roomindex].UsersList[i].Username != "u" && Rooms[roomindex].UsersList[i].Ready)
{
try
{
if (Rooms[roomindex].UsersList[i].HomeUser)
{
if (Rooms[roomindex].TalkingPos == x)
{
Rooms[roomindex].UsersList[i].VideoSock.Send(videodata, 0, videodata.Length, SocketFlags.None);
}
}
else
{
Rooms[roomindex].UsersList[i].VideoSock.Send(videodata, 0, videodata.Length, SocketFlags.None);
}
}
catch
{
}
}
}
}
else
{
// wait untill there are enough data
//break;
}
}
}
catch (Exception exo)
{
Rooms[roomindex].UsersList[x].VideoList.Clear();
}
}
}
catch (Exception VideoSendingException)
{
logerror(VideoSendingException);
}
Rooms[roomindex].DoneProcessing = true;
//Thread.CurrentThread.Abort();
}
I know that the code is not clear, and in order to help me, you have a lot of questions to ask me, i will try my best to help my self and not ask many noob questions, but your guidance is what i seek.
Because of all the troubles im facing with this code, i know there must be a better practice. and appreciate any pointer in the right direction.
the application as i said is a video conference application that should support up to 99 client in each session. (is that even doable?!)
thank you.