you don't check the return values of any call (aka good weather programming)
sp1 = new SerialPort("COM4", 9600);
rv = sp1.open();
why do you assume sp1 = new SerialPort("COM4", 9600); returns a valid value?
sp1 = new SerialPort("COM4", 9600);
if (sp1 != null)
{
try
{
rv = sp1.open();
}
catch()
{
// open failed ...
}
}