|
Hello,
I am currently developing a Quiz that has to send the result of each participant to me via a TCP-connection. On the server computer (with the "master" application) the results get evaluated. It is of vital importance that the results are transmitted rapidly (that's why TCP rather than uploading result or such).
The connectin itself works, I just struggle with the StreamReader (and StreamWriter). This is my code as of now:
Client-Sending:
private void onButtonClick() {
TcpClient client;
client = new TcpClient("127.0.0.1", 25543);
StreamWriter writer = new StreamWriter(client.GetStream());
writer.Write("Test");
writer.Flush();
}
Server-Receiving (runs in Timer):
TcpClient client = new TcpClient();
TcpListener listener = new TcpListener(25543);
if (listener.Pending()) {
message = null;
client = listener.AcceptTcpClient();
StreamReader reader = new StreamReader(client.GetStream());
while (reader.Peek() != -1)
{
message += reader.Read().ToString();
}
MessageBox.Show(message);
}
Right now, when I run this, the message that gets displayed in the MessageBox is a very long number, for the message "Test" it's "84101115116". How can I convert this integer back to the original string "Test", so that the original message is displayed correctly in my server application?
I know that e.g. 84 in ASCII is the letter T, however the other numbers are different. Can some1 help?
Greetings
~Veraner
|
|
|
|
|
The Read method reads a character as an int. I believe that if you do:
message += (char)reader.Read(); (without the ToString())
it will probably work.
Yet, I believe your code has many problems...
I would recommend using WriteLine, not only Write, after all TCP/IP packets may be split in many messages. Your while() will fail if that happens.
Also, as you don't use another thread or asynchronous calls, the server is only able to deal with one client at a time.
|
|
|
|
|
Thank you - that solved my issue!
By now I made a seperate threat for this function and will have a look towards the WriteLine / while part.
|
|
|
|
|
Hi,
I have a datagridview. Under column is copy id from other tabel, i want auto change id with -1 to only number without -. Replace is dont working for datagridview. Who can help me?
This string work only for the textbox how can i change it for datagridview?
identity = identity.Replace("-", "");
modified 1-Mar-15 11:16am.
|
|
|
|
|
That should work for your DataGridView if the cell contains a string, but not if it is a numeric value.
|
|
|
|
|
Hmm that is numeric value. How connect you tabel to other tabel with relations?
|
|
|
|
|
Sorry, no idea what that means.
If it's a numeric value then you probably need to add an event handler to change it when it gets displayed.
|
|
|
|
|
sdfsdfsdfewrew3feff wrote: How connect you tabel to other tabel with relations? Usually using a number (often BIGINT) or a GUID.
If you need to remove the "-" sign from a number, consider multiplying it with -1, as opposed to converting it to a string.
Also, if it is a key-field (only there to keep relations with other records) then it should never be formatted or presented to the user at all.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
I have been writing a generic factory class; in pruned-down to walk-the-dog-bits-left-out form:
public class VTBunchOLists : List<IEnumerable<T>>
{
private bool isInt;
public VTBunchOLists()
{
isInt = typeof(T) == typeof(Int32);
}
public Int32 TToInt32(T value)
{
return (Int32)Convert.ChangeType(value, typeof(Int32));
}
public void Add(T howmanyT, bool ascending = true)
{
if (isInt)
{
var range = CreateRange(1, TToInt32(howmanyT), ascending);
this.Add(range as IEnumerable<T>);
}
}
private IEnumerable<int> CreateRange(Int32 howMany, bool ascending = true)
{
var range = Enumerable.Range(start, end);
return (ascending) ? range : range.Reverse();
}
} Here's what concerns me:
1. there's no way to constrain the Type of T to certain ValueTypes ... that I've found in my research. I guess I could look at the Type of T in the 'ctor and return null, or throw an error, if the Type didn't match what I wanted to handle, but that seems less than elegant to me.
2. obviously I'll do quite a different thing (not shown in the code) if T is a double, since you can't use Enumerable.Range for producing anything but and integer Range.
3. similarly the required casting of an integer (or double) range to IEnumerable<t> to be able to add it to the collection kind of gives me an itch I can't scratch, but what do you think ?
4. (related to concern #1) while Enumerable.Range(start#int, end#int) returns a nice IEnumerable<int> ... and so the return value of the factory is an "un-evaluated" IEnumerable, since you have to use a List<doulbe> to create the range of doubles, the return value of the factory will be an "evaluated" structure. That lack of "symmetry" bothers me, but I see no way around this ... now ... except to make the factory return a List<List<T>> ... mmmm ...
Why am I doing this: well, I've already written separate implementations for Int32 and Double, and I'm curious to see what's involved in making it generic. And, there is some very fancy stuff in the current implementations (not shown in the code here) that could be consolidated.
thanks, Bill
«I'm asked why doesn't C# implement feature X all the time. The answer's always the same: because no one ever designed, specified, implemented, tested, documented, shipped that feature. All six of those things are necessary to make a feature happen. They all cost huge amounts of time, effort and money.» Eric Lippert, Microsoft, 2009
modified 1-Mar-15 7:20am.
|
|
|
|
|
You can constrain it to a value type by making the whole class generic and adding the struct constraint:
public class VTBunchOLists<T> : List<IEnumerable<T>> where T : struct
{
private bool isInt;
public VTBunchOLists()
{
isInt = typeof(T) == typeof(Int32);
}
...
} (You have to use struct because ValueType isn't the root type for value types - it's just used for boxing)
And that might help a little - you can't use a where constraint on any sealed class (and all the primitives are sealed IIRC)
I have to say I don't like runtime type rejection in the constructor: I know what you mean, but it goes against my grain somewhat to force a run time error for something that should be a compile time problem!
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Thanks, Griff !
I don't like Type rejection at run-time either, so 'struct will have to do.
If you have the bandwidth, I'd appreciate your reaction to a new "concern" I added to my original post: #4.
cheers, Bill
«I'm asked why doesn't C# implement feature X all the time. The answer's always the same: because no one ever designed, specified, implemented, tested, documented, shipped that feature. All six of those things are necessary to make a feature happen. They all cost huge amounts of time, effort and money.» Eric Lippert, Microsoft, 2009
|
|
|
|
|
Hi Bill,
as far as I know my Roslyn yet, with it you could write a source analysis that checks whether you try to use the factory class with anything other than the value types that it is intended for and include that check into your build process, so you can get an error pre runtime. Other than that, while not very beautiful, checking in the c'tor seems to be an agreed upon solution.
- Sebastian
|
|
|
|
|
Thanks, Sebastian,
It is interesting to speculate what a "range" of structs ... where the struct is a user-defined collection of whatever Types ... might be ... but I see no practical reason to go there, and so I think that if I do use the generic version, I will do run-time Type checking; I'd rather do that than engage in any reflection.
However, it's also interesting to think about if using some new feature in Roslyn (I'm using CTP 6 Visual Studio 2015 now for testing) might somehow reduce the "cost" of reflection. I'm not aware of any meta-programming features new in Roslyn ... yet.
cheers, Bill
«I'm asked why doesn't C# implement feature X all the time. The answer's always the same: because no one ever designed, specified, implemented, tested, documented, shipped that feature. All six of those things are necessary to make a feature happen. They all cost huge amounts of time, effort and money.» Eric Lippert, Microsoft, 2009
|
|
|
|
|
The core of the problem seems to be that you need to be able to add an increment to an instance of the generic type parameter T . There are various solutions for this - I tend to use some code adapted from the MiscUtil library[^]:
public static class GenericOperator<T>
{
private static readonly Func<T, T, T> _addChecked = Create<T>(Expression.AddChecked);
public static Func<T, T, T> AddChecked
{
get { return _addChecked; }
}
private static Func<T, T, TResult> Create<TResult>(Func<Expression, Expression, BinaryExpression> body)
{
try
{
Type typeT = typeof(T);
var left = Expression.Parameter(typeT, "left");
var right = Expression.Parameter(typeT, "right");
if (typeT.IsEnum)
{
Type enumType = Enum.GetUnderlyingType(typeT);
var x = Expression.Convert(left, enumType);
var y = Expression.Convert(right, enumType);
Expression op = body(x, y);
if (op.Type == enumType) op = Expression.Convert(op, typeT);
return Expression.Lambda<Func<T, T, TResult>>(op, left, right).Compile();
}
return Expression.Lambda<Func<T, T, TResult>>(body(left, right), left, right).Compile();
}
catch (InvalidOperationException ex)
{
string message = ex.Message;
return delegate { throw new InvalidOperationException(message); };
}
catch (ArgumentException ex)
{
string message = ex.Message;
return delegate { throw new InvalidOperationException(message); };
}
}
}
Since there's no way to get an instance of the generic type parameter that represents "1 ", you'll need to pass in the increment value to your Add function:
public class VTBunchOLists<T> : List<IEnumerable<T>>
{
private static readonly Func<T, T, T> AddChecked = GenericOperator<T>.AddChecked;
public VTBunchOLists()
{
}
public void Add(T startAt, T increment, int howMany, bool ascending = true)
{
IEnumerable<T> range = CreateRange(startAt, increment, howMany);
if (!ascending) range = range.Reverse();
Add(range);
}
private static IEnumerable<T> CreateRange(T startAt, T increment, int howMany)
{
T current = startAt;
for (int i = 0; i < howMany; i++)
{
yield return current;
current = AddChecked(current, increment);
}
}
}
If you want the contained ranges to be evaluated eagerly, you can do that in the Add method:
Add(range.ToList());
You can now use this class for any type which implements the addition operator:
var bunchOInt32s = new VTBunchOLists<int>();
bunchOInt32s.Add(10, 1, 15);
var bunchODoubles = new VTBunchOLists<double>();
bunchODoubles.Add(Math.PI, Math.E, 10, false);
public class Foo
{
public int Number { get; set; }
public static Foo operator+(Foo left, Foo right)
{
return new Foo { Number = left.Number + right.Number };
}
}
var bunchOFoos = new VTBunchOLists<Foo>();
bunchOFoos.Add(new Foo(), new Foo { Number = 5 }, 3);
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I am crafting a guitar tuner and I came across a problem. I am not sure how I can have the audio input be set to 440hz. Any suggestions?
|
|
|
|
|
Ask on a hardware site, rather than software?
What does this have to do with C#?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Supposing you want use C# to write your program, it seems that you are a little bit confused: do you want pickup the A tone (La 440Hz) with microphone or you want your speakers play a sinusoidal 440Hz tone?
But anyway why don't you start using search engines? Googling you'll find many open source programs that do that.
One from FFT Guitar Tuner from Codeproject[^], or this from Sourgeforge[^]...
|
|
|
|
|
|
Currently we're using in code <System.Web.Services.WebService(Namespace:="https://ourservice/")> to set the namespace, can this be done in web.config, instead? I've looked but can't find where?
VS2008, ASMX web service.
|
|
|
|
|
|
|
When I add an item to the datagridview (from another form), it shows up just fine. But when I try to add another item to the datagridview, only the new item appears, and the previous one gets thrown out, it appears.
Note that I'm using .Hide, and .Show, to move between two forms (add_form and main_form). I've tried using .ShowDialog to see if it would fix the problem, but instead I get multiple instances of the same window open after moving back and forth between forms.
How can I fix this problem?
Here is the code that adds to the DGV:
private void add_Click(object sender, EventArgs e)
{
invmain invmainobject = new invmain();
switch(combobox1.SelectedIndex)
{
case 0:
invmainobject.datagridview1.Rows.Add(itembox.Text, quantitybox.Text);
break;
case 1:
invmainobject.datagridview2.Rows.Add(itembox.Text, quantitybox.Text);
break;
case 2:
invmainobject.datagridview3.Rows.Add(itembox.Text, quantitybox.Text);
break;
case 3:
invmainobject.datagridview4.Rows.Add(itembox.Text, quantitybox.Text);
break;
default:
MessageBox.Show("Please select a category.\t\t");
combobox1.Focus();
return;
}
invmainobject.Show();
this.Close();
|
|
|
|
|
I suspect your problem has nothing to do with adding items to the datagrid, but everything to do with how you're handling the forms that contain/manipulate the grid:
Quote: but instead I get multiple instances of the same window open after moving back and forth between forms.
You have to show the code that is creating/showing these forms as you are probably creating new instances of the forms instead of managing the existing forms properly.
|
|
|
|
|
Here is the code for the main page where the tab control is, with the four DGV's:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class invmain : Form
{
public invmain()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
cover form1 = new cover();
form1.Show();
this.Hide();
}
private void button2_Click(object sender, EventArgs e)
{
additem form1 = new additem();
form1.Show();
this.Hide();
}
private void deletebutton_Click(object sender, EventArgs e)
{
DialogResult deleteitem = MessageBox.Show("Delete selected item?\t\t\t", "Delete Item", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (deleteitem == DialogResult.Yes)
{
foreach (DataGridViewRow item in this.datagridview1.Rows)
{
datagridview1.Rows.RemoveAt(item.Index);
}
foreach (DataGridViewRow item in this.datagridview2.Rows)
{
datagridview2.Rows.RemoveAt(item.Index);
}
foreach (DataGridViewRow item in this.datagridview3.Rows)
{
datagridview3.Rows.RemoveAt(item.Index);
}
foreach (DataGridViewRow item in this.datagridview4.Rows)
{
datagridview4.Rows.RemoveAt(item.Index);
}
MessageBox.Show("Item deleted.\t\t\t", "Delete Item", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
And here is the additem page, where after clicking add, the item and quantity should be added to the appropriate DGV after selecting a valid category:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class additem : Form
{
public additem()
{
InitializeComponent();
datetimelabel.Text = DateTime.Now.ToString("MM/dd/yyyy");
this.quantitybox.KeyPress += new KeyPressEventHandler(quantitybox_KeyPress);
}
private void additem_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
invmain form1 = new invmain();
form1.Show();
this.Hide();
}
private void quantitybox_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !(char.IsDigit(e.KeyChar) || e.KeyChar == '\b');
}
private void add_Click(object sender, EventArgs e)
{
invmain invmainobject = new invmain();
switch(combobox1.SelectedIndex)
{
case 0:
invmainobject.datagridview1.Rows.Add(itembox.Text, quantitybox.Text);
break;
case 1:
invmainobject.datagridview2.Rows.Add(itembox.Text, quantitybox.Text);
break;
case 2:
invmainobject.datagridview3.Rows.Add(itembox.Text, quantitybox.Text);
break;
case 3:
invmainobject.datagridview4.Rows.Add(itembox.Text, quantitybox.Text);
break;
default:
MessageBox.Show("Please select a category.\t\t", "Required Field Missing", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
combobox1.Focus();
return;
}
if (string.IsNullOrWhiteSpace(this.itembox.Text))
{
MessageBox.Show("The 'Item' field is required.\t\t\t", "Required Field Missing", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
itembox.Focus();
return;
}
if (string.IsNullOrWhiteSpace(this.quantitybox.Text))
{
MessageBox.Show("The 'Quantity' field is required.\t\t\t", "Required Field Missing", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
quantitybox.Focus();
return;
}
invmainobject.Show();
this.Close();
}
private void button1_Click_1(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
if (open.ShowDialog() == DialogResult.OK)
uploadpic.Image = Bitmap.FromFile(open.FileName);
}
}
}
Note that I'm no longer using .ShowDialog(), because of the trouble of multiple forms I got.
modified 27-Feb-15 18:16pm.
|
|
|
|
|
OK, a few things. First, you haven't solved the problem of multiple forms. You've just hidden them and never reusing the them. You're creating a new instance of every form on every button click, even your MAIN FORM!!
You're using the default names for all of your controls. DON'T! I have no idea what "button1" does and, in a years time, neither will you. Always give your controls and variables meaningful names.
If these two button controls on your main form with the grids and just there to get data from the user to add to the grid, you should create an instance of the data entry form and show it with ShowDialog. When the user clicks OK on that form control will return to the line right after the ShowDialog call. You can then get the data from that form, put it in your grids, then Dispose the form.
Next, when you go and clear all the rows from your datagrids, you don't need loops to delete each row from the girds. Look at the documentation for the Rows collection. There's a Clear() method on it. Call that and you wipe out every row in your datagrid in a single line of code.
|
|
|
|
|