blah blah blah is here! blah blah » Close

535 views

Winsock

up0down
link

Is Winsock usable in C#? f so is there any good documentation on it? Especially making a client?
thanks!

last answered 2 years ago

1 answers

up0down
link

You could by why would you when you have System.Net

up0down
link

I'm communicating with a really proprietary peice of hardware(non windows). I have information on how to connect with it via winsock, and I really wanna play it safe.

up0down
link

Aww gotcha!
You can reference the winsock dll from with in References under your Project in the Solution Explorer. Now that i think of it.. Winsock is a COM component right?

up0down
link

Does not look like it is a COM component. Trying to add winsock.dll is telling me that it's not valid either.

up0down
link

You can call a static dl like this as an example:
<code>
using System;
using System.Runtime.InteropServices;
class MainApp
{
[DllImport("user32.dll", EntryPoint="MessageBox")]
public static extern int MessageBox(int hWnd, String strMessage, String
strCaption, uint uiType);
public static void Main()
{
MessageBox( 0, "Hello, this is PInvoke in operation!", ".NET", 0 );
}
}
</code>

up0down
link

would I need to do that to every function call I make?

up0down
link

You might want to create a wrapper class that makes calls to these DLLs entries. (These DLLs are created using CDecl instead of StdDecl which date back before COM making them not registerable).

up0down
link

Although winsock is available via DllImport, it is considered lecacy. I suggest you look at System.Net and System.Sockets. It has similiar concepts to winsock, but a lot more features!! Take a lot at it, the namespace is relatively small --and powerful!

up0down
link

Sorry, System.Net.Sockets... DAMN EDIT BUTTON!!!

up0down
link

I was also looking for a WinSock'y feature in .NET but the Socket class is a bit more advanced and the old vb "withevents" is not included. I tried making a client and server class for easy serving and connecting with the async part of sockets, but I found it to be very unstable. It procured some uncatchable errors (NullReferenceException's). Someone mentioned it could be a finalizer bug, so I was sure to keep references to the IAsyncCallback methods. Didn't help. So I made a NON-"async" socket class where I use 1 thread for listening to data and 1 thread for listening on new connections.
Hope this will help someone. This was what I was hoping to find finished and done on the net for me so I did not have to make it myself.
(I'm pretty fresh on C# and i didnt find a way to make SocketConnection noninstansiable. Its should only be a hidden parentclass for SocketServer and SocketClient. Anyone know how I do this?)
Sample code (start class with Main()):

public class socktesting{
static SocketServer ss = new SocketServer();
static SocketClient sc = new SocketClient();

public static void Main(){
testserver();
testclient();
System.Threading.Thread.Sleep(4000); //wait 4 seconds
sc.Disconnect(); //Disconnect client from server
while(true){
System.Windows.Forms.Application.DoEvents();
}
}
//The server part.
public static void testserver(){
ss.SetConnectHandler(new ConnectHandler(SOnConnection));
ss.SetDisconnectHandler(new DisconnectHandler(SOnDisconnect));
ss.SetDataArrivalHandler(new DataArrivalHandler(SOnDataArrival));
ss.Serve(1111); //Serve on port 1111
}
public static bool SOnConnection(string ID){
Debug.WriteLine("Machine: " + ID + " connected.");
ss.SendData("Hello mr Client",ID);
return true; //Keep the connection (return false for disconnect)
}
public static void SOnDisconnect(string ID){
Debug.WriteLine("Machine: " + ID + " DISconnected.");
}
public static void SOnDataArrival(string data, string ID){
Debug.WriteLine("Data from "+ID+": " + data);
ss.SendData("I got your data!",ID);
}



//The client part.
public static void testclient(){
sc.SetDisconnectHandler(new DisconnectHandler(COnDisconnect));
sc.SetDataArrivalHandler(new DataArrivalHandler(COnDataArrival));
sc.Connect("127.0.0.1",1111);
sc.SendData("Hello server! I am your new client!");
}

public static void COnDisconnect(string ID){
Debug.WriteLine("Server: " + ID + " DISconnected.");
}
public static void COnDataArrival(string data, string ID){
Debug.WriteLine("Data from server "+ID+": " + data);
}

}

The classes:
using System;
using System.Diagnostics;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Collections;
namespace socks{
public delegate void DataArrivalHandler(string data, string remoteID); //Delegate for DataArrival Events
public delegate void DisconnectHandler(string remoteID); //Delegate for Disconnect Events
public delegate bool ConnectHandler(string remoteID); //Delegate for new Connection
/// <summary>
/// Summary description for no.
/// </summary>
public class SocketConnection{
private const int BUFFER_SIZE = 1024;
public Socket sock = null;
private string datareceived = "";
private Thread dataThread = null;
public string LocalID = "";
public string RemoteID = "";
//Callbacks to OnDataArrival and OnDisconnect
public event DataArrivalHandler daEvent;
public event DisconnectHandler disEvent;
public virtual void SetDataArrivalHandler(DataArrivalHandler da){
try{
daEvent += new DataArrivalHandler(da);
}catch(Exception ex){
throw new Exception("SetDataArrivalHandler feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}

public virtual void SetDisconnectHandler(DisconnectHandler dis){
try{
disEvent += new DisconnectHandler(dis);
}catch(Exception ex){
throw new Exception("SetDisconnectHandler feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}

public SocketConnection(){
//Init...?
}
public void Start(Socket s){
try{
sock=s;
LocalID = sock.LocalEndPoint.ToString();
RemoteID = sock.RemoteEndPoint.ToString();
dataThread = new Thread(new ThreadStart(DataReceive));
dataThread.Priority=ThreadPriority.AboveNormal;
dataThread.Start();
}catch(Exception ex){
throw new Exception("Start feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}
public void DataReceive(){
try{
Debug.WriteLine("Data came from " + RemoteID);
while(true){
byte[] recibuffer = new byte[BUFFER_SIZE];
int c = 0;
string data="";
lock(sock){
while(sock.Available>0){
c = sock.Receive(recibuffer, 0, BUFFER_SIZE, SocketFlags.None);
string recidata = System.Text.Encoding.Default.GetString(recibuffer, 0, c);
data+=recidata;
//Debug.WriteLine("<-("+LocalID+")-"+recidata);
}
}
if(data.Length>0){
//If callback is definert, call it.
if(daEvent!=null){
daEvent(data,RemoteID);
}else{
lock(datareceived){
datareceived +=data;
}
}
}
if(!SockConnected(sock)){
try{ //shutdown the socket
sock.Shutdown(SocketShutdown.Both);
}catch(Exception){}
try{ //close the socket
sock.Close();
sock=null;
}catch(Exception){}
if(disEvent!=null){
disEvent(RemoteID);
}
return; //exit the thread
}
Thread.Sleep(5);
System.Windows.Forms.Application.DoEvents();
}
}catch(Exception ex){
Debug.WriteLine("DataReceive ERROR: " + ex.Message);
}
}
private bool SockConnected(Socket s){
bool f = s.Poll(1, SelectMode.SelectRead);
if (f == true && s.Available == 0){
return false;
}
return true;
}
//Use this to get data, unless a callback is defined
public string GetData(){
try{
//Debug.WriteLine("Getdata polling...");
string ret = "";
lock(datareceived){
ret=datareceived;
datareceived="";
}
return ret;
}catch(Exception ex){
throw new Exception("GetData feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}

//Send data
public void SendData(string data){
if(sock!=null){
try{
byte[] bytes = System.Text.Encoding.Default.GetBytes(data);
lock(sock){
sock.Send(bytes, 0, bytes.Length, SocketFlags.None);
}
Thread.Sleep(30);
}catch(Exception ex){
throw new Exception("SendData feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}
}
//Disconnect from the server and disconnect the dataarrival listener thread
public void Disconnect(){
if(sock!=null){
try{
sock.Shutdown(SocketShutdown.Both);
sock.Close();
dataThread.Abort();
sock=null;
}catch(Exception ex){
throw new Exception("Disconnect feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}
}
}
/// <summary>
/// Summary description for no.
/// </summary>
public class SocketClient{
private SocketConnection sc = null;
private DataArrivalHandler globDA=null;
private DisconnectHandler globDIS=null;
//Connect to a server + port
public string Connect(string Hostname, int Port){
try{
IPEndPoint epServer = new IPEndPoint(System.Net.Dns.Resolve(Hostname).AddressList[0],Port );
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(epServer);
sc = new SocketConnection();
if(globDA!=null) sc.SetDataArrivalHandler(globDA);
if(globDIS!=null) sc.SetDisconnectHandler(globDIS);
sc.Start(sock);
return sc.RemoteID;
}catch(Exception ex){
throw new Exception("Connect feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}
public virtual void SetDataArrivalHandler(DataArrivalHandler da){
globDA=da;
if(sc!=null)sc.SetDataArrivalHandler(da);
}

public virtual void SetDisconnectHandler(DisconnectHandler dis){
globDIS=dis;
if(sc!=null)sc.SetDisconnectHandler(dis);
}
public string GetData(){
return sc.GetData();
}

public void SendData(string data){
sc.SendData(data);
}
public void Disconnect(){
sc.Disconnect();
}
}
/// <summary>
/// Summary description for no.
/// </summary>
public class SocketServer{
private Thread connectionsThread = null;
private Socket sock = null;
private ArrayList arrConnections = new ArrayList();
DataArrivalHandler globDA=null;
DisconnectHandler globDIS=null;
//Event for Connect
public event ConnectHandler conEvent;
public virtual void SetConnectHandler(ConnectHandler co){
try{
conEvent += new ConnectHandler(co);
}catch(Exception ex){
throw new Exception("SetConnectHandler feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}

public virtual void SetDataArrivalHandler(DataArrivalHandler da){
globDA = da;
lock(arrConnections){
foreach(SocketConnection sc in arrConnections){
sc.SetDataArrivalHandler(da);
}
}
}

public virtual void SetDisconnectHandler(DisconnectHandler dis){
globDIS = dis;
lock(arrConnections){
foreach(SocketConnection sc in arrConnections){
sc.SetDisconnectHandler(dis);
}
}
}
public void OnClientDisconnect(string ID){
SocketConnection remsc = null;
lock(arrConnections){
foreach(SocketConnection sc in arrConnections){
if(sc.RemoteID.Equals(ID)){
remsc = sc;
break;
}
}
arrConnections.Remove(remsc);
}
}
public string GetData(string ID){
lock(arrConnections){
foreach(SocketConnection sc in arrConnections){
if(sc.RemoteID.Equals(ID)){
return sc.GetData();
}
}
}
return "";
}
public void SendData(string data, string ID){
lock(arrConnections){
foreach(SocketConnection sc in arrConnections){
if(sc.RemoteID.Equals(ID)){
sc.SendData(data);
return;
}
}
}
return;
}
public int GetConnectionCount(){
int ret = 0;
lock(arrConnections){
ret = arrConnections.Count;
}
return ret;
}
public void Serve(int Port){
try{
if(sock!=null) try{Stop();}catch(Exception){}
IPEndPoint ipEP = new IPEndPoint(IPAddress.Any, Port);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try{
sock.Bind(ipEP);
}catch(Exception ex){
throw new Exception("Bind feilet: [Exception:" + ex.GetType().ToString() + ", " + ex.Message + "]");
}
sock.Listen(1000);
sock.Blocking=false;
connectionsThread = new Thread(new ThreadStart(AwaitConnections));
connectionsThread.Start();
}catch(Exception ex){
throw new Exception("Serve feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}
public void Stop(){
try{
foreach(SocketConnection sc in arrConnections){
if(sc!=null)sc.Disconnect();
}
connectionsThread.Abort();

if(sock!=null){
lock(sock){
try{
sock.Shutdown(SocketShutdown.Both);
}catch(Exception){}
sock.Close();
sock=null;
}
}
}catch(Exception ex){
throw new Exception("Stop feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}
private void AwaitConnections(){
try{
while(true){
Socket newsock = null;
lock(sock){
try{
while(true){
newsock = null;
newsock = sock.Accept();

if(newsock!=null){
bool accept=true;

if(conEvent!=null) accept = conEvent(newsock.RemoteEndPoint.ToString()); //call onconnect event

if(accept){ //Accept connection
//Debug.WriteLine("Ny connection opprettet!");
SocketConnection sc = new SocketConnection();
if(globDA!=null){//DataArrival Callback set
sc.SetDataArrivalHandler(globDA);
}
if(globDIS!=null){//Disconnect Callback set
sc.SetDisconnectHandler(globDIS);
}
sc.SetDisconnectHandler(new DisconnectHandler(OnClientDisconnect));
sc.Start(newsock);
Debug.WriteLine("CONNECTIONS:" + GetConnectionCount());
lock(arrConnections){
arrConnections.Add(sc);
}

}else{ //Close the connection
Debug.WriteLine("Ny connection nektet!");
try{
newsock.Shutdown(SocketShutdown.Both);
}catch(Exception){}
try{
newsock.Close();
newsock=null;
}catch(Exception){}

}

}
}
}catch(SocketException ex){
if(ex.ErrorCode!=10035){ //if NOT "A non-blocking socket operation could not be completed immediately"
Debug.WriteLine("sock.Accept() feilet? [(" +ex.ErrorCode+ ") "+ex.GetType().ToString()+","+ex.Message+"]");
}
}catch(Exception ex){
Debug.WriteLine("sock.Accept() feilet? ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}
System.Windows.Forms.Application.DoEvents();
Thread.Sleep(100);
}
}catch(Exception){
//Debug.WriteLine("AwaitConnections feilet! ["+ex.GetType().ToString()+","+ex.Message+"]");
}
}
}
}

This post was imported from csharpfriends, if you have a similiar question please ask it again.

All previous members have been migrated, hope you enjoy the new platform!

Feedback