I've already got some code in place which allows me to connect to a smtp server and verify the ip(just checks for a timeout.). anyway, i now need the app to check that the user and password its given has access to the smtp to send email. the code i have is as follows. -
public ScriptingTelnet(string Address, int Port, int CommandTimeout)
-
{
-
address = Address;
-
port = Port;
-
timeout = CommandTimeout;
-
}
-
-
-
public bool Connect()
-
{
-
string []aliases;
-
IPAddress[] addr;
-
try
-
{
-
IPHostEntry IPHost = Dns.Resolve(address);
-
aliases = IPHost.Aliases;
-
addr = IPHost.AddressList;
-
}
-
catch
-
{
-
return false;
-
}
-
-
try
-
{
-
// Try a blocking connection to the server
-
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
-
iep = new IPEndPoint(addr[0],port);
-
s.Connect(iep) ;
-
-
-
// If the connect worked, setup a callback to start listening for incoming data
-
AsyncCallback recieveData = new AsyncCallback( OnRecievedData );
-
s.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData , s );
-
-
// All is good
-
return true;
-
}
-
catch
-
{
-
// Something failed
-
return false;
-
}
-
-
}
-
so to do my test i call something like: -
objActiveSolutions.ScriptingTelnet telnet = new objActiveSolutions.ScriptingTelnet(this.tbSMTPIP.Text, 25, 10);
-
if(telnet.Connect())
-
{
-
//do something
-
}
-
Anyone know who i can modify this to allow me to authenticate the user and pass?
Many Thanks,
Piercy
14 9124
If you are talking to the SMTP server, look up the SMTP commands.
Giving the "EHLO <your computer identity>"+[enter] should give you a response back telling you what AUTH types are available.
You can then send the correct sequence of commands to AUTH the user.
The rfc for the AUTH command extension can be found here
If you are talking to the SMTP server, look up the SMTP commands.
Giving the "EHLO <your computer identity>"+[enter] should give you a response back telling you what AUTH types are available.
You can then send the correct sequence of commands to AUTH the user.
The rfc for the AUTH command extension can be found here
yes, i know the commands i need to use or i cna look them up. but im just not sure how i would send the commands to the server from the program.
im basically doing a check for a smtp server, my users use the application to send emails to people in a database.
now on settings up the app they admin will need to put in the smtp ip, username and password if required. the code i have above check the ip address responds. now i need it to authenticate and check it responds at the same time.
any ideas on how to send the commands from the app? just and ehlo or something then i can work out the auth and stuff myself.
Thanks once again,
Piercy
In the program I made for smtp, I had an active socket connection the smtp server. (I presume that this is a real smtp server yes?)
On the socket I send the commands as ASCII strings
Format of EHLO: -
string computername="PlaterComputer";
-
string domainname="mydomain.com";
-
string ehlostring= "EHLO "+computername+"."+domainname+"\r\n";
-
Then the response back should follow the SMPT standards. It's possible the server will NOT list the available ATUH types (I believe it is supposed to though)
That link I send in the past message has example communications, i.e.:
C: EHLO mycomputer.mydomain.com
S: 250-mail.mydomain.com
S: 250 AUTH CRAM-MD5 DIGEST-MD5
That server will accept CRAM-MD5 and DIGEST-MD5 auth types.
Was that what you were looking for or were you looking for the actual how to send it using code thing?
In the program I made for smtp, I had an active socket connection the smtp server. (I presume that this is a real smtp server yes?)
On the socket I send the commands as ASCII strings
Format of EHLO: -
string computername="PlaterComputer";
-
string domainname="mydomain.com";
-
string ehlostring= "EHLO "+computername+"."+domainname+"\r\n";
-
Then the response back should follow the SMPT standards. It's possible the server will NOT list the available ATUH types (I believe it is supposed to though)
That link I send in the past message has example communications, i.e.:
That server will accept CRAM-MD5 and DIGEST-MD5 auth types.
Was that what you were looking for or were you looking for the actual how to send it using code thing?
It doesn thave to use the code i provided. it would just be helpful if it did. im playing around with it now and the smtp server im using (yes it's real) -
250 - AUTH GSSAPI NTLM LOGIN
-
250 - AUTH =LOGIN
-
thats part of what my server responds when ehlo it using cmd prmpt.
would you be able to give me the exact piece of code to send to the server. ie, i think the coding im using does this...
Socket s = new socket........
so the how would i send the commands soemthing like s.command?
250 - AUTH GSSAPI NTLM LOGIN
250 - AUTH =LOGIN
So your server would prefer that use "LOGIN", but allows those other two types as well.
Well once you have you Socket created and connected (You can use the TcpClient object if you prefer)
So consider the following:
I have a function: -
private void Write(TcpClient tcpc, byte[] buff)
-
{
-
try
-
{
-
tcpc.GetStream().Write(buff, 0, buff.Length);
-
}
-
catch (IOException ioe)
-
{
-
bool ignoreme = (ioe.Message == "");
-
tcpc.Close();
-
}
-
catch (SocketException se)
-
{
-
bool ignoreme = (se.Message == "");
-
tcpc.Close();
-
}
-
}
-
Then I could use: -
string authstring="AUTH LOGIN\r\n";
-
byte[] authbytes=Encoding.ASCII.GetBytes(authstring);
-
//you need a byte[] to send on the socket
-
// Encoding.ASCII is your friend
-
-
write(mytcpclient, authbytes);//send the command string
-
-
//you will then have to wait and read the response back
-
//my actual "read" function used to read the response is pretty big
-
//but I will include a little bit to get you started maybe:
-
private string GetResponse(TcpClient tcpc)
-
{
-
string gotin = "";
-
while (tcpc.GetStream().DataAvailable)
-
{
-
gotin += ((char)tcpc.GetStream().ReadByte());
-
}
-
return gotin;
-
}
-
You would then use the write/read functions to send you commands and verify the response.
250 - AUTH GSSAPI NTLM LOGIN
250 - AUTH =LOGIN
So your server would prefer that use "LOGIN", but allows those other two types as well.
Well once you have you Socket created and connected (You can use the TcpClient object if you prefer)
So consider the following:
I have a function: -
private void Write(TcpClient tcpc, byte[] buff)
-
{
-
try
-
{
-
tcpc.GetStream().Write(buff, 0, buff.Length);
-
}
-
catch (IOException ioe)
-
{
-
bool ignoreme = (ioe.Message == "");
-
tcpc.Close();
-
}
-
catch (SocketException se)
-
{
-
bool ignoreme = (se.Message == "");
-
tcpc.Close();
-
}
-
}
-
Then I could use: -
string authstring="AUTH LOGIN\r\n";
-
byte[] authbytes=Encoding.ASCII.GetBytes(authstring);
-
//you need a byte[] to send on the socket
-
// Encoding.ASCII is your friend
-
-
write(mytcpclient, authbytes);//send the command string
-
-
//you will then have to wait and read the response back
-
//my actual "read" function used to read the response is pretty big
-
//but I will include a little bit to get you started maybe:
-
private string GetResponse(TcpClient tcpc)
-
{
-
string gotin = "";
-
while (tcpc.GetStream().DataAvailable)
-
{
-
gotin += ((char)tcpc.GetStream().ReadByte());
-
}
-
return gotin;
-
}
-
You would then use the write/read functions to send you commands and verify the response.
right, im feeling like an idiot at the moment... lol... anyway, this is the code i had and it seems to contain all the information i need.. not definate but i think it does. -
using System;
-
using System.Net;
-
using System.Net.Sockets;
-
using System.Text;
-
using System.IO;
-
using System.Threading ;
-
-
namespace objActiveSolutions
-
{
-
/// <summary>
-
/// Summary description for clsScriptingTelnet.
-
/// </summary>
-
public class ScriptingTelnet
-
{
-
private IPEndPoint iep ;
-
private AsyncCallback callbackProc;
-
private string address ;
-
private int port ;
-
private int timeout;
-
private Socket s ;
-
Byte[] m_byBuff = new Byte[32767];
-
private string strWorkingData = ""; // Holds everything received from the server since our last processing
-
private string strFullLog = "";
-
-
public ScriptingTelnet(string Address, int Port, int CommandTimeout)
-
{
-
address = Address;
-
port = Port;
-
timeout = CommandTimeout;
-
}
-
-
-
private void OnRecievedData( IAsyncResult ar )
-
{
-
// Get The connection socket from the callback
-
Socket sock = (Socket)ar.AsyncState;
-
-
// Get The data , if any
-
int nBytesRec = sock.EndReceive( ar );
-
-
if( nBytesRec > 0 )
-
{
-
// Decode the received data
-
string sRecieved = CleanDisplay(Encoding.ASCII.GetString( m_byBuff, 0, nBytesRec ));
-
-
// Write out the data
-
if (sRecieved.IndexOf("[c") != -1) Negotiate(1);
-
if (sRecieved.IndexOf("[6n") != -1) Negotiate(2);
-
-
Console.WriteLine(sRecieved);
-
strWorkingData += sRecieved;
-
strFullLog += sRecieved;
-
-
-
// Launch another callback to listen for data
-
AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
-
sock.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData , sock );
-
-
}
-
else
-
{
-
// If no data was recieved then the connection is probably dead
-
Console.WriteLine( "Disconnected", sock.RemoteEndPoint );
-
sock.Shutdown( SocketShutdown.Both );
-
sock.Close();
-
//Application.Exit();
-
}
-
}
-
-
private void DoSend(string strText)
-
{
-
try
-
{
-
Byte[] smk = new Byte[strText.Length];
-
for ( int i=0; i < strText.Length ; i++)
-
{
-
Byte ss = Convert.ToByte(strText[i]);
-
smk[i] = ss ;
-
}
-
-
s.Send(smk,0 , smk.Length , SocketFlags.None);
-
}
-
catch
-
{
-
//MessageBox.Show("ERROR IN RESPOND OPTIONS");
-
}
-
}
-
-
private void Negotiate(int WhichPart)
-
{
-
StringBuilder x;
-
string neg;
-
if (WhichPart == 1)
-
{
-
x = new StringBuilder();
-
x.Append ((char)27);
-
x.Append ((char)91);
-
x.Append ((char)63);
-
x.Append ((char)49);
-
x.Append ((char)59);
-
x.Append ((char)50);
-
x.Append ((char)99);
-
neg = x.ToString();
-
}
-
else
-
{
-
-
x = new StringBuilder();
-
x.Append ((char)27);
-
x.Append ((char)91);
-
x.Append ((char)50);
-
x.Append ((char)52);
-
x.Append ((char)59);
-
x.Append ((char)56);
-
x.Append ((char)48);
-
x.Append ((char)82);
-
neg = x.ToString();
-
}
-
SendMessage(neg,true);
-
}
-
-
private string CleanDisplay(string input)
-
{
-
-
input = input.Replace("(0x (B","|");
-
input = input.Replace("(0 x(B","|");
-
input = input.Replace(")0=>","");
-
input = input.Replace("[0m>","");
-
input = input.Replace("7[7m","[");
-
input = input.Replace("[0m*8[7m","]");
-
input = input.Replace("[0m","");
-
return input;
-
}
-
-
-
-
-
/// <summary>
-
/// Connects to the telnet server.
-
/// </summary>
-
/// <returns>True upon connection, False if connection fails</returns>
-
public bool Connect()
-
{
-
string []aliases;
-
IPAddress[] addr;
-
try
-
{
-
IPHostEntry IPHost = Dns.Resolve(address);
-
aliases = IPHost.Aliases;
-
addr = IPHost.AddressList;
-
}
-
catch
-
{
-
return false;
-
}
-
-
try
-
{
-
// Try a blocking connection to the server
-
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
-
iep = new IPEndPoint(addr[0],port);
-
s.Connect(iep) ;
-
-
-
// If the connect worked, setup a callback to start listening for incoming data
-
AsyncCallback recieveData = new AsyncCallback( OnRecievedData );
-
s.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData , s );
-
-
// All is good
-
return true;
-
}
-
catch
-
{
-
// Something failed
-
return false;
-
}
-
-
}
-
-
-
public void Disconnect()
-
{
-
if (s.Connected) s.Close();
-
}
-
-
/// <summary>
-
/// Waits for a specific string to be found in the stream from the server
-
/// </summary>
-
/// <param name="DataToWaitFor">The string to wait for</param>
-
/// <returns>Always returns 0 once the string has been found</returns>
-
public int WaitFor(string DataToWaitFor)
-
{
-
// Get the starting time
-
long lngStart = DateTime.Now.AddSeconds(this.timeout).Ticks;
-
long lngCurTime = 0;
-
-
while (strWorkingData.ToLower().IndexOf(DataToWaitFor.ToLower()) == -1)
-
{
-
// Timeout logic
-
lngCurTime = DateTime.Now.Ticks;
-
if (lngCurTime > lngStart)
-
{
-
throw new Exception("Timed Out waiting for : " + DataToWaitFor);
-
}
-
Thread.Sleep(1);
-
}
-
strWorkingData = "";
-
return 0;
-
}
-
-
-
/// <summary>
-
/// Waits for one of several possible strings to be found in the stream from the server
-
/// </summary>
-
/// <param name="DataToWaitFor">A delimited list of strings to wait for</param>
-
/// <param name="BreakCharacters">The character to break the delimited string with</param>
-
/// <returns>The index (zero based) of the value in the delimited list which was matched</returns>
-
public int WaitFor(string DataToWaitFor,string BreakCharacter)
-
{
-
// Get the starting time
-
long lngStart = DateTime.Now.AddSeconds(this.timeout).Ticks;
-
long lngCurTime = 0;
-
-
string[] Breaks = DataToWaitFor.Split(BreakCharacter.ToCharArray());
-
int intReturn = -1;
-
-
while (intReturn == -1)
-
{
-
// Timeout logic
-
lngCurTime = DateTime.Now.Ticks;
-
if (lngCurTime > lngStart)
-
{
-
throw new Exception("Timed Out waiting for : " + DataToWaitFor);
-
}
-
-
Thread.Sleep(1);
-
for (int i = 0 ; i < Breaks.Length ; i++)
-
{
-
if (strWorkingData.ToLower().IndexOf(Breaks[i].ToLower()) != -1)
-
{
-
intReturn = i ;
-
}
-
}
-
}
-
return intReturn;
-
-
}
-
-
-
/// <summary>
-
/// Sends a message to the server
-
/// </summary>
-
/// <param name="Message">The message to send to the server</param>
-
/// <param name="SuppressCarriageReturn">True if you do not want to end the message with a carriage return</param>
-
public void SendMessage(string Message, bool SuppressCarriageReturn)
-
{
-
strFullLog += "\r\nSENDING DATA ====> " + Message.ToUpper() + "\r\n";
-
Console.WriteLine("SENDING DATA ====> " + Message.ToUpper());
-
-
if (! SuppressCarriageReturn)
-
{
-
DoSend(Message + "\r");
-
}
-
else
-
{
-
DoSend(Message);
-
}
-
}
-
-
-
/// <summary>
-
/// Sends a message to the server, automatically appending a carriage return to it
-
/// </summary>
-
/// <param name="Message">The message to send to the server</param>
-
public void SendMessage(string Message)
-
{
-
strFullLog += "\r\nSENDING DATA ====> " + Message.ToUpper() + "\r\n";
-
Console.WriteLine("SENDING DATA ====> " + Message.ToUpper());
-
-
DoSend(Message + "\r");
-
}
-
-
-
/// <summary>
-
/// Waits for a specific string to be found in the stream from the server.
-
/// Once that string is found, sends a message to the server
-
/// </summary>
-
/// <param name="WaitFor">The string to be found in the server stream</param>
-
/// <param name="Message">The message to send to the server</param>
-
/// <returns>Returns true once the string has been found, and the message has been sent</returns>
-
public void WaitAndSend(string WaitFor,string Message)
-
{
-
this.WaitFor(WaitFor);
-
SendMessage(Message);
-
-
-
}
-
-
-
/// <summary>
-
/// Sends a message to the server, and waits until the designated
-
/// response is received
-
/// </summary>
-
/// <param name="Message">The message to send to the server</param>
-
/// <param name="WaitFor">The response to wait for</param>
-
/// <returns>True if the process was successful</returns>
-
public string SendAndWait(string Message, string WaitFor)
-
{
-
-
SendMessage(Message);
-
this.WaitFor(WaitFor);
-
return strWorkingData;
-
}
-
-
-
-
public int SendAndWait(string Message, string WaitFor, string BreakCharacter)
-
{
-
SendMessage(Message);
-
int t = this.WaitFor(WaitFor,BreakCharacter);
-
return t;
-
}
-
-
-
/// <summary>
-
/// A full log of session activity
-
/// </summary>
-
public string SessionLog
-
{
-
get
-
{
-
return strFullLog;
-
}
-
}
-
-
-
/// <summary>
-
/// Clears all data in the session log
-
/// </summary>
-
public void ClearSessionLog()
-
{
-
strFullLog = "";
-
}
-
-
-
/// <summary>
-
/// Searches for two strings in the session log, and if both are found, returns
-
/// all the data between them.
-
/// </summary>
-
/// <param name="StartingString">The first string to find</param>
-
/// <param name="EndingString">The second string to find</param>
-
/// <param name="ReturnIfNotFound">The string to be returned if a match is not found</param>
-
/// <returns>All the data between the end of the starting string and the beginning of the end string</returns>
-
public string FindStringBetween(string StartingString, string EndingString, string ReturnIfNotFound)
-
{
-
int intStart;
-
int intEnd;
-
-
intStart = strFullLog.ToLower().IndexOf(StartingString.ToLower());
-
if (intStart == -1)
-
{
-
return ReturnIfNotFound;
-
}
-
intStart += StartingString.Length;
-
-
intEnd = strFullLog.ToLower().IndexOf(EndingString.ToLower(),intStart);
-
-
if (intEnd == -1)
-
{
-
// The string was not found
-
return ReturnIfNotFound;
-
}
-
-
// The string was found, let's clean it up and return it
-
return strFullLog.Substring(intStart, intEnd-intStart).Trim();
-
}
-
-
-
}
-
}
-
-
i know this is a lot of code to paste, i did look for a online code dump to make it easier but couldnt find one.
would you be able to give me a quick example (using this if you can) on how to AUTH to a server preferably in the login encoding and/or a way to check for the auth the server requires and auth usign that(because thats the eventual need).
Thanks you very much, youve been a big help... even though i havent got my result yet im undertsanding it alot more.
Thanks,
Piercy
Well I think you can do this: -
string authstart="AUTH LOGIN\r\n";
-
SendMessage(authstart,true);
-
//you need a "\r\n" I think, maybe not, whatever though
-
Now the problem is, you don't know what the response will be that you're waiting for, other then it will start with a 3-digit number and end with a "\r" or "\r\n".
It didn't look like you had a way to read a response and process it. The AUTH types require you to examine the reply to determine your response.
Appendix B: A LOGIN SMTP AUTH Conversation
A LOGIN SMTP Authentication conversation looks something like the following (after the mail server has indicated its support for the LOGIN mechanism):
C: AUTH LOGIN
S: 334 VXNlcm5hbWU6
C: d2VsZG9u
S: 334 UGFzc3dvcmQ6
C: dzNsZDBu
S: 235 2.0.0 OK Authenticated
Lines 2-5 of the conversation contain base64-encoded information. The same conversation, with base64 strings decoded, reads:
C: AUTH LOGIN
S: 334 Username:
C: weldon
S: 334 Password:
C: w3ld0n
S: 235 2.0.0 OK Authenticated
And the Convert object has .ToBase64String() ability for you.
Well I think you can do this: -
string authstart="AUTH LOGIN\r\n";
-
SendMessage(authstart,true);
-
//you need a "\r\n" I think, maybe not, whatever though
-
Now the problem is, you don't know what the response will be that you're waiting for, other then it will start with a 3-digit number and end with a "\r" or "\r\n".
It didn't look like you had a way to read a response and process it. The AUTH types require you to examine the reply to determine your response.
And the Convert object has .ToBase64String() ability for you.
you still need to use the econding .ascii.getbytes because Convet.ToBase64String needs it in byte[] form. anyway, thats a greta help. tells em what to do really well. im still stuck with how i verify that connection. after all thats what its all about. some sort fo command i would need to be auth for for it to work? would i still need to be abel to return something from the server to verify the conenction?
or any other possible ways to verify the username and password against the ipaddress?
Some servers have a VRFY command, but it's been my experiance that very few implement it.
Other than connecting to the smtp server and running the AUTH command sequence, I don't know of any way to validate username and passwords against a mail server.
Some servers have a VRFY command, but it's been my experiance that very few implement it.
Other than connecting to the smtp server and running the AUTH command sequence, I don't know of any way to validate username and passwords against a mail server.
ok, looks like my client will have to go without the verification feature. ill verify theres a smtp server there then its there own job to make sure they give my the correct username and password.
Thanks very much for your help. even though id dint get the result i wanted i learnt a lot while doing it.
Thanks once again,
Piercy
Are you not allowed to modify the code you provided to me?
It might be possible for you to simple "add in" the response reading functions that you need.
Are you not allowed to modify the code you provided to me?
It might be possible for you to simple "add in" the response reading functions that you need.
i can modify it all i wish. also, the s3xy person next to me(lol).. recomended calling a hidden command prompt using the system.diagnostics namespace.
have you got any ideas for modifying that code then?
THanks,
Piercy
Well what you would need is a "readline" from the response stream.and then have access to everything up till that point.
All server responses start with 3digits and end with the newline terminator.
If you could find a way to get at that it might work.
edit: going to post ina enw thread as its a totally different problem now.. thanks for your help.
Sign in to post your reply or Sign up for a free account.
Similar topics
by: Dan |
last post by:
I'm writing a simplistic telnet client in VB6 and I've run into a small
snag. The program has a textbox to write in the string to be sent using
..SendData and has another textbox that displays...
|
by: Mark Carter |
last post by:
I'm trying to create a mail server in Twisted.
I either get
SMTPSenderRefused
or
SMTPException: SMTP AUTH extension not supported by server.
What do I need to do to get it to work?
|
by: David Hughes |
last post by:
I wonder if anyone can help me resolve this problem. Although my ISP (One
and One) provides the facility to run Python 2.2 CGI programs, their
technical support people don't seem to have any Python...
|
by: LutherRevisited |
last post by:
Ok with some tweaking I got it to where I could send through my local isp's
smtp server, but I am restricted to sending the message from my ISP's mail
account. When I respond to Yahoo mail, I want...
|
by: LutherRevisited |
last post by:
To clear up something which Gerhard advised me on regarding the login method.
I've found that AOL's smtp server is unique compared to every other one I've
seen. If you type auth plain, it will...
|
by: z f |
last post by:
Hi,
i'm sending mail from the aspx page on the server.
it is running on hosting,
so i configure the System.Web.Mail.SmtpMail.SmtpServer property to my mail
server.
but problem is that sender...
|
by: the_ricka |
last post by:
Hi all,
I'm fairly new to python, but very excited about it's potential.
I'm trying to write a simple program that will accept input from a
command line and send email. The parameters I used on...
|
by: Jeff |
last post by:
I am receiving the following error:
// error: System.Net.Mail.SmtpException: The SMTP server requires a
secure connection or the client was not authenticated. The server
response was: 5.7.0 No...
|
by: John Drako |
last post by:
Currently, I run postfix on my own server to send message from my site
(password requests, account activation notices and other messages).
I have phpMailer on the server and all the messages...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
| | |