29. august 2005 - 10:02Der er
26 kommentarer og 1 løsning
Sockets: Send og receive i et hug
Hejsa,
Jeg er igang med noget socketprogrammering. Det drejer sig om en SIP klient til ip-telefoni... men det er sådan set ikke væsentligt.
Jeg skal sende en besked til min SIP server (går fint lige nu), problmerne opstår når jeg skal modtage noget fra SIP serveren....
Når jeg sender en besked til SIP serveren svarer den tilbage at den har modtaget min besked. Den besked kan jeg ikke få mit program til at fange...
Lidt kode:
using System; using System.Text; using System.IO; using System.Threading; using System.Net; using System.Net.Sockets;
namespace tmSock { /// <summary> /// /// </summary> public class sock { public sock() { // // TODO: Add constructor logic here // }
private static Socket ConnectSocket(string server, int port) { Socket s = null; IPHostEntry hostEntry = null;
// Get host related information. hostEntry = Dns.Resolve(server);
// Loop through the AddressList to obtain the supported AddressFamily. This is to avoid // an exception that occurs when the host IP Address is not compatible with the address family // (typical in the IPv6 case). foreach(IPAddress address in hostEntry.AddressList) { IPEndPoint ipe = new IPEndPoint(address, port); Socket tempSocket = new Socket(ipe.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
Socket c = new Socket(endPoint.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
// Creates an IpEndPoint to capture the identity of the sending host. IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); EndPoint senderRemote = (EndPoint)sender;
// Binding is required with ReceiveFrom calls. c.Bind(endPoint); byte[] msg = new Byte[2048];
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Efter du har sendt beskeden afsted lukker du forbindelsen med s.Close(), hvilket er årsagen til at du ikke modtager noget respons. Hvis du fjerner s.Close() skulle det virke lidt bedre.
Det var egentlig heller ikke meningen at der skulle være s.Close() med... blot en lille test på programmet fra min side, da jeg fik følgende fejl meddl.
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in system.dll
Additional information: Adressen, der blev anmodet om, er ikke gyldig i sin kontekst
Denne fejl opstår også nu (jeg har fjernet s.Close()) programmet stopper når der bliver sagt c.Bind(endPoint)
ja jeg har lånt derfra - men kun i begrænset omfang. Jeg SKAL bruge UDP og ikke TCP som eksemplet... når man bruger UDP kan man ikke connect'e socket'en da protokollen jo er connectionless...
jeg har et sniffer program - og det er 110% sikkert at serveren sender svar - det skal den gøre (det er en kommercielt SIP server, der er til at stole på ;-)
Desuden går programmet jo ned - så der er noget galt i min kode!
Remarks Use the Bind method if you need to use a specific local endpoint. You must call Bind before you can call the Listen method. You do not need to call Bind before using the Connect method unless you need to use a specific local endpoint. You can use the Bind method on both connectionless and connection-oriented protocols.
Before calling Bind, you must first create the local IPEndPoint from which you intend to communicate data. If you do not care which local address is assigned, you can create an IPEndPoint using IPAddress.Any as the address parameter, and the underlying service provider will assign the most appropriate network address. This might help simplify your application if you have multiple network interfaces. If you do not care which local port is used, you can create an IPEndPoint using 0 for the port number. In this case, the service provider will assign an available port number between 1024 and 5000.
If you use the above approach, you can discover what local network address and port number has been assigned by calling the LocalEndPoint. If you are using a connection-oriented protocol, LocalEndPoint will not return the locally assigned network address until after you have made a call to the Connect or EndConnect method. If you are using a connectionless protocol, you will not have access to this information until you have completed a send or receive.
Note If you intend to receive multicasted datagrams, you must call the Bind method with a multicast port number. Note You must call the Bind method if you intend to receive connectionless datagrams using the ReceiveFrom method. Note If you receive a SocketException when calling the Bind method, use SocketException.ErrorCode to obtain the specific error code. Once you have obtained this code, you can refer to the Windows Socket Version 2 API error code documentation in MSDN for a detailed description of the error.
Socket s = new Socket(ipe.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
if (s == null) return ("Connection failed");
// Send request to the server. s.SendTo(bytesSent, ipe);
int bytes = 0; string page = "";
// Creates an IpEndPoint to capture the identity of the sending host. IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); EndPoint senderRemote = (EndPoint)sender;
IPEndPoint denneMaskine = new IPEndPoint(IPAddress.Any, 0);
s.Bind(denneMaskine) giver runtime fejl: ------------------------------------ An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in system.dll
Additional information: Der blev angivet et ugyldigt argument ------------------------------------
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint denneMaskine = new IPEndPoint(IPAddress.Any, 0); s.Bind(denneMaskine);
virker fint hos mig
noget helt andet - hvordan skal serveren vide hvilken port du lytter på når du først finder port nummeret efter at du har sendt til serveren ??
Blot det problem, at serveren sender to beskeder tilbage, men jeg fanger kun den sidste. De kommer på samme portnr.
Jeg tror problemet er, at der ganske enkelt når at komme den første besked før min socket "c" er klar til at tage imod...
Jeg har testet det ved at lave et lille konsol program der blot står lytter, det starter jeg før jeg sender - det program kan godt modtage den første besked...
Men jeg synes det er lidt mærkeligt at det kan gå så stærk at 5 liniers kode ikke kan nå at følge med... Måske en løsning kunne være at få kogt programmet ned til kun at bruge den selv samme socket???
Jeg er gået over til UdpClient - nemmere for mig lige nu, bliver dog nok nødt til at vende tilbage til en "rigtig" socket igen... men den tid den sorg...
Jeg har ikke brug for yderligere her for nuværende.
Men ellers tak - og tak i det hele taget!
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.