Cannot connect to socket on local machine - sockets
I did a simple translation of the example C# code here:
let socket_CreateBindListen (sv_ : string) (pt_ : int) : Socket option =
let (he : IPHostEntry) = Dns.GetHostEntry(sv_)
let rsock, ipe =
he.AddressList
|> Seq.map (fun s ->
let (ipe2 : IPEndPoint) = new IPEndPoint (s, pt_)
let (rsock2 : Socket) = new Socket (ipe2.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
rsock2.Connect ipe2 ///// <---- No connection could be made because the target machine actively refused it
rsock2, ipe2)
|> Seq.find (fun (s, t) -> s.Connected)
try
rsock.Bind ipe
rsock.Listen 10
printfn "%s now listening on port %d" sv_ pt_
Some (rsock)
with
| _ ->
printfn "Failed to connect to %s on port %d" sv_ pt_
None
socket_CreateBindListen "127.0.0.1" 50000
I made sure to first open port 50000 on my machine for TCP for both inbound and outbound connections. (I even tried disabling the firewall completely.) Nothing seems to be working. I keep getting the error message:
No connection could be made because the target machine actively refused it.
I am using Windows 8. I would really appreciate some pointers on what else I might try.
Thanks in advance for your time.
EDIT
I hope I am not violating any of StackOverflow's posting policies by blogging about my progress here.
I have updated the code to the following:
let socket_CreateBindListen (sv_ : string) (pt_ : int) : Socket option =
let (he : IPHostEntry) = Dns.GetHostEntry(sv_)
let rsock, ipe =
he.AddressList
|> Seq.map (fun s ->
let (ipe2 : IPEndPoint) = new IPEndPoint (s, pt_)
let (rsock2 : Socket) = new Socket (ipe2.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
try
rsock2.Connect ipe2
rsock2, ipe2
with
| _ ->
null, null)
|> Seq.find (fun (s, t) -> (s <> null) && (s.Connected))
try
rsock.Bind ipe
rsock.Listen sbl
printfn "%s now listening on port %d" sv_ pt_
Some (rsock)
with
| _ ->
printfn "Failed to connect to %s on port %d" sv_ pt_
None
Now I am getting the following error:
KeyNotFoundException was unhandled
An unhandled exception of type 'System.Collections.Generic.KeyNotFoundException' occurred in FSharp.Core.dll
I have looked extensively on Google and Bing, without any luck.
EDIT 2
As requested by Jack P., here is the output from netstat -a, as well as what happens when the binary is executed:
PS C:\Users\shredderroy> netstat -a
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:80 SPEEDMACHINE:0 LISTENING
TCP 0.0.0.0:135 SPEEDMACHINE:0 LISTENING
TCP 0.0.0.0:445 SPEEDMACHINE:0 LISTENING
TCP 0.0.0.0:2179 SPEEDMACHINE:0 LISTENING
TCP 0.0.0.0:49152 SPEEDMACHINE:0 LISTENING
TCP 0.0.0.0:49153 SPEEDMACHINE:0 LISTENING
TCP 0.0.0.0:49154 SPEEDMACHINE:0 LISTENING
TCP 0.0.0.0:49155 SPEEDMACHINE:0 LISTENING
TCP 0.0.0.0:49156 SPEEDMACHINE:0 LISTENING
TCP 192.168.0.139:139 SPEEDMACHINE:0 LISTENING
TCP 192.168.0.139:49159 bn1wns2011708:https ESTABLISHED
TCP 192.168.0.139:49167 vc-in-f108:imaps ESTABLISHED
TCP 192.168.0.139:49171 vc-in-f108:imaps ESTABLISHED
TCP 192.168.0.139:49239 a23-67-250-112:http CLOSE_WAIT
TCP [::]:80 SPEEDMACHINE:0 LISTENING
TCP [::]:135 SPEEDMACHINE:0 LISTENING
TCP [::]:445 SPEEDMACHINE:0 LISTENING
TCP [::]:2179 SPEEDMACHINE:0 LISTENING
TCP [::]:49152 SPEEDMACHINE:0 LISTENING
TCP [::]:49153 SPEEDMACHINE:0 LISTENING
TCP [::]:49154 SPEEDMACHINE:0 LISTENING
TCP [::]:49155 SPEEDMACHINE:0 LISTENING
TCP [::]:49156 SPEEDMACHINE:0 LISTENING
UDP 0.0.0.0:500 *:*
UDP 0.0.0.0:4500 *:*
UDP 0.0.0.0:5355 *:*
UDP 127.0.0.1:53194 *:*
UDP 127.0.0.1:60316 *:*
UDP 127.0.0.1:61644 *:*
UDP 192.168.0.139:137 *:*
UDP 192.168.0.139:138 *:*
UDP [::]:500 *:*
UDP [::]:4500 *:*
UDP [::]:5355 *:*
UDP [fe80::b193:4f6:d053:6324%20]:546 *:*
PS C:\Users\shredderroy> cd "C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\bin\Debug
"
PS C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\bin\Debug> .\SocketTests_Server.exe
Unhandled Exception: System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it [::1]:50000
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at SocketTests_Server.TestModule_1.heo#22.Invoke(IPAddress s) in C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\TestModule_1.fs:line 25 at Microsoft.FSharp.Collections.SeqModule.TryFind[T](FSharpFunc`2 predicate, IEnumerable`1 source)
at SocketTests_Server.TestModule_1.socket_CreateBindListen_1(String sv_, Int32 pt_) in C:\Users\shredderroy\Documents\Visual Studio
2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\TestModule_1.fs:line 20
at SocketTests_Server.Program.Main(String[] args) in C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\Program.fs:line 9
PS C:\Users\shredderroy\Documents\Visual Studio 2012\Projects\FSharp\SocketTests_Server\SocketTests_Server\bin\Debug>
I am going to keep trying. So far I have added my programme, SocketTests_Server.exe, to the list of allowed programmes in Windows Firewall, opened the relevant port for inbound and outbound connections, disabled the firewall completely--all to no avail.
I think what is happening is that you are connecting twice, one of the addresses connects fine. Your code then keeps looking through the remaining addresses and tries to connect again.
Your code is lacking the equivalent of break in the C# code.
Some possible solutions:
use a while loop instead of Seq.map
Use a reference variable inside the map
Compress all the code into Seq.find and remove the call to map (probably the most elegant)
I translated the code from the page you linked -- it compiles, though I haven't tried running it.
open System
open System.Text
open System.Net
open System.Net.Sockets
let connectSocket (server : string, port : int) : Socket option =
// Get host related information.
let hostEntry = Dns.GetHostEntry 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).
hostEntry.AddressList
|> Seq.tryPick (fun address ->
let ipe2 = IPEndPoint (address, port)
let rsock2 = new Socket (ipe2.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
rsock2.Connect ipe2
if rsock2.Connected then
Some rsock2
else None)
// This method requests the home page content for the specified server.
let socketSendReceive (server : string, port : int) : string =
let request =
sprintf "GET / HTTP/1.1\r\nHost: %s\r\nConnection: Close\r\n\r\n" server
let bytesSent =
Encoding.ASCII.GetBytes request
let bytesReceived = Array.zeroCreate 256
// Create a socket connection with the specified server and port.
match connectSocket (server, port) with
| None ->
"Connection failed"
| Some s ->
// Send request to the server.
s.Send (bytesSent, Array.length bytesSent, SocketFlags.None)
|> ignore
// Receive the server home page content.
let mutable bytes = 0
let mutable page =
sprintf "Default HTML page on %s:\r\n" server
// The following will block until the page is transmitted.
while bytes > 0 do
bytes <- s.Receive (bytesReceived, Array.length bytesReceived, SocketFlags.None)
page <- page + Encoding.ASCII.GetString (bytesReceived, 0, bytes)
page
//
let main args =
let port = 80
let host =
if Array.isEmpty args then
// If no server name is passed as argument to this program,
// use the current host name as the default.
Dns.GetHostName ()
else
args.[0]
socketSendReceive (host, port)
|> Console.WriteLine
EDIT: I did a little digging, and "actively refused" is the key to that error message, according to: No connection could be made because the target machine actively refused it. In short, double-check that the server you're trying to connect to is set up properly; when the connection is actively refused, there's no firewall problem -- the server is actually rejecting your connection.
If you're absolutely certain the server is set up correctly, there's one last thing you could try. According to Socket Connection Is Actively Refused (MSDN Forums), you may need to use the IPAddress.NetworkToHostOrder Method to set the port value correctly for the IPEndPoint. In that case, just add this as the first line in my connectSocket function (above):
let port = IPAddress.NetworkToHostOrder port
EDIT 2: Looking at the netstat information you posted -- there's no server LISTENING on port 50000. If you're sure the server software is set up correctly, make sure it's using the port you want (and not just choosing a random port).
First, I would like to thank everyone, in particular, #Jack P. and #John Palmer, for reading my code and offering very good and instructive suggestions. Your guidance is greatly appreciated.
I have circumvented the problem described above by using the TcpListener and TcpClient classes instead. So I thought I would write the simple F# translations of this server function and this client function, which together implement the server and client. Hopefully, this sample code will save other beginners some time.
Server
let connectAndListen () : unit =
let (laddr : IPAddress) = IPAddress.Parse ("127.0.0.1")
let lpt = 32000
let (svr : TcpListener) = new TcpListener (laddr, lpt)
try
svr.Start ()
let (bta : byte[]) = Array.create 256 (byte (0))
while true do
printfn "Waiting for a connection..."
let (cl : TcpClient) = svr.AcceptTcpClient ()
printfn "Connected"
let (ns : NetworkStream) = cl.GetStream ()
let mutable (i : int) = ns.Read (bta, 0, (Array.length bta))
while i <> 0 do
let (dat : string) = System.Text.Encoding.ASCII.GetString (bta, 0, i)
printfn "Received: %s" dat
let (msg : byte[]) = System.Text.Encoding.ASCII.GetBytes (dat.ToUpper ())
ns.Write (msg, 0, (Array.length msg))
printfn "Sent: %s" (dat.ToUpper ())
i <- ns.Read (bta, 0, (Array.length bta))
cl.Close ()
with
| excp ->
printfn "%s" excp.Message
svr.Stop ()
Client
let connect (sv_ : string) (pt_ : int) (msg_ : string) : unit =
try
let cl = new TcpClient (sv_, pt_)
let (dat : byte[]) = System.Text.Encoding.ASCII.GetBytes msg_
let (st : NetworkStream) = cl.GetStream ()
st.Write (dat, 0, (Array.length dat))
printfn "Sent: %s" msg_
let (rdat : byte[]) = Array.create 256 (byte (0))
let (i : int) = st.Read (rdat, 0, (Array.length rdat))
let (rsp : string) = System.Text.Encoding.ASCII.GetString (rdat, 0, i)
printfn "Received: %s" rsp
st.Close ()
st.Dispose ()
with
| :? ArgumentNullException as excp ->
printfn "ArgumentNullException encountered: %s" excp.Message
| :? SocketException as excp ->
printfn "SocketException encountered: %s" excp.Message
printfn "Press ENTER to continue"
Console.ReadLine () |> ignore
Place the code in separate projects, compile and run them. They work on my machine.
Related
socket.gaierror: [Errno 11001] getaddrinfo failed while connecting to ngrok server
I wrote a simple server code using socket module forward the listening port using ngrok but when i try to connect to ngrok provided url it gives error socket.gaierror: [Errno 11001] getaddrinfo failed Server Code import socket server = socket.socket() host = "localhost" port = 5002 server.bind((host,port)) print("Started Listening.........") server.listen() con, addr = server.accept() print("Connection is accepted from :",str(addr)) while True: data = con.recv(1024).decode() if not data: break print("From Connected User :",str(data)) data = str(data).upper() print("Received from User: " + str(data)) data = input("Enter message::::") con.send(data.encode()) con.close() Client Code import socket host = "tcp://0.tcp.in.ngrok.io:18376" port = 5002 client = socket.socket() client.connect((host,port)) mess = input("Enter message::") while mess!='q': client.send(mess.encode()) data = client.recv(1024).decode() print("FROM SERVER = ",data) mess = input("Enter message ::") client.close() I am creating a tcp tunnel using ngrok at 5002 port ngrok tcp 5002 It generates Web Interface http://127.0.0.1:4040 Forwarding tcp://0.tcp.in.ngrok.io:18376 -> localhost:5002 i am using this tcp url in my client host code host = "tcp://0.tcp.in.ngrok.io:18376" I tried removing port number and tried only tcp://0.tcp.in.ngrok.io but nothing happend Can you guide me how to connect to this tcp tunnel from socket module because i am pretty new to socket programming.
Create haskel socket client
I try to connect to created socket by haskell: -- Logger putStrLn "Create socket" sock_logger <- socket AF_INET Stream 0 putStrLn "Bind socket" connect sock_logger (SockAddrInet 5000 0) putStrLn "Listen socket" listen sock_logger 2 putStrLn "Logger listening on port 5000..." (conn_logger, _) <- accept sock_logger putStrLn "Logger connection accepted" Scocket already created by other application. But after connect sock_logger (SockAddrInet 5000 0) i get helloworld-exe.EXE: Network.Socket.connect: <socket: 440>: failed (Cannot assign requested address (WSAEADDRNOTAVAIL)) How can i connect to socket as client (without creation new socket) All sockets i create with SockAddrInet 5000 0. Can it depends on addlress (maybe need 127.0.0.1 instead localhost?)
Perhaps you're looking for tupleToHostAddress, as in connect sock_logger (SockAddrInet 5000 (tupleToHostAddress (127, 0, 0, 1)))
Thx Daniel Wagner, it's really need to use tupleToHostAddress (127, 0, 0, 1) and listen ... is wrong. Right version: putStrLn "Create socket" sock_logger <- socket AF_INET Stream 0 putStrLn "Bind socket" connect sock_logger (SockAddrInet 5000 (tupleToHostAddress (127, 0, 0, 1))) putStrLn "Connected to logger on port 5000..."
Connecting two computers in different networks using socket and Port forwarding
I have set up a simple client-server communication code and it works well in my computer when my computer itself acts as a server and the client. Now I am trying to run this same code on two different computers in different networks( different locations) where my computer will act as a server and my friend's computer as a client. I have done port forwarding in my router as well as in my friend's router for the port which we are trying to communicate. We both have set up a static IP in our internal network behind the router. We both had shutdown the firewall while running the code. I am running my code on Jupiter notebook and the same is my friend too. here is my server code: import socket import threading HEADER = 64 PORT = 5064 SERVER = '0.0.0.0' ADDR = (SERVER, PORT) FORMAT = 'utf-8' DISCONNECT_MESSAGE = "quit" Receive_from_client = "get info" server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(ADDR) def handle_client(conn, addr): print("\n" + f"[NEW Connection] detected from IP: {addr[0]} & Port:{addr[1]} ") conn.send(f"connected to server {ADDR}".encode(FORMAT)) connected =True while connected: msg_length = conn.recv(HEADER).decode(FORMAT) # decode the msg from byte to utf-8 format if msg_length: msg_length = int(msg_length) msg = conn.recv(msg_length).decode(FORMAT) if msg == DISCONNECT_MESSAGE: connected = False print(f" [Client][{addr}] {msg}") print("Your session is disconnected") break if msg == Receive_from_client: print("\n" + f"Send your msg to client with IP: {addr[0]}") thread = threading.Thread(target = send2client, args = (conn, addr)) thread.start() print(f" [Client][{addr}] {msg}") conn.send(f"Msg received by server with IP:{addr[0]}".encode(FORMAT)) conn.close() server.close() def start(): server.listen() print("\n"+ f"[LISTENING] Server is listening from IP: {SERVER} ") while True: conn, addr = server.accept() thread = threading.Thread(target = handle_client, args = (conn, addr)) thread.start() Here is the client code import socket import threading HEADER = 64 PORT = 5064 FORMAT = 'utf-8' DISCONNECT_MESSAGE = "quit" SERVER = '103.192.207.250' # SERVERS public IP ADDR = (SERVER, PORT) client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(ADDR) def send2server(): while True: msg = input() message = msg.encode(FORMAT) msg_lenght = len(message) send_length = str(msg_lenght).encode(FORMAT) send_length += b' '*(HEADER - len(send_length)) client.send(send_length) client.send(message) print(client.recv(2048).decode(FORMAT)) if msg == DISCONNECT_MESSAGE: print("session closed") client.close() def start(): print("\n"+ f"[LISTENING] client is listening from IP: {ADDR} ") send2server() I have opened the port by going on windows firewall defender and selecting new inbound and outbound rules to open 5064 TCP port. but still, the code doesn't works.. my server keeps waiting for connection and the client-side after few seconds of running gives this error: TCP error code 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond Even while my server is listening from port 5064 when I scan this port to check if the port is open or not it says closed. How do I check if the port I have forwarded is for sure open and also how do I get this thing work? I have tried all of this and if there is any other thing I am missing please tell. I am struggling to get this work for the past 3 days.
Destination Unreachable (Port Unreachable) using Haskell
Using Wireshark to debug, I receive the following error when sending UDP packets on localhost: Destination Unreachable (Port Unreachable) Checksum: 0x0000 (Illegal) I am constructing my server first on a port between 10000 - 15000 using startServer :: Port -> IO Server startServer port = withSocketsDo $ do -- Look up the server address and port information. addrs <- getAddrInfo (Just $ defaultHints { addrFlags = [AI_PASSIVE] }) Nothing (Just port) let serverAddress = head addrs -- Bind to the socket. sock <- socket (addrFamily serverAddress) Datagram defaultProtocol bindSocket sock (addrAddress serverAddress) -- Create the server and run the client send and receive threads. clients <- newMVar $ createEmptyClients let server = Server sock port clients _ <- forkIO $ forever $ receiveClientJoin server return server I am listening for new clients connecting via UDP using -- | Connected a client to the server. receiveClientJoin :: Server -> IO () receiveClientJoin server = do print "Receiving" (msg, _, clSockAddr) <- recvFrom (sSocket server) 4096 print $ "Server received client join message: " ++ msg And I am connecting to the server with clients using connectToServer port = do -- Get the server's address and port information. addrInfo <- getAddrInfo Nothing (Just "localhost") (Just port) let serverAddr = head addrInfo sock <- socket (addrFamily serverAddr) Datagram defaultProtocol sendTo sock "Hello from this client!" (addrAddress serverAddr) Why are my clients' packets not finding the server?
The problem is you are listening on an IPv6 address and trying to connect to an IPv4 address. This is actually a slightly common problem. For example, I ran across this issue when working with commsec. Consider the fragments where you discover your AddrInfo: import Network.Socket main :: IO () main = do let port = "2474" addrs <- getAddrInfo (Just $ defaultHints { addrFlags = [AI_PASSIVE] }) Nothing (Just port) let serverAddress = head addrs print serverAddress addrInfo <- getAddrInfo Nothing (Just "localhost") (Just port) let serverAddr = head addrInfo print serverAddr Now the output will vary by machine, but on one of my CentOS systems with both IPv4 and IPv6 addresses the output clearly shows the second (connect) address is IPv6 while the first (listen) address is IPv4: AddrInfo {addrFlags = [AI_PASSIVE], addrFamily = AF_INET, addrSocketType = Stream, addrProtocol = 6, addrAddress = 0.0.0.0:2474, addrCanonName = Nothing} AddrInfo {addrFlags = [AI_ADDRCONFIG,AI_V4MAPPED], addrFamily = AF_INET6, addrSocketType = Stream, addrProtocol = 6, addrAddress = [::1]:2474, addrCanonName = Nothing} One solution is to force a particular version of IP via a hint or an address (ex. an IPv4 address as in my comment). The hint solution is probably more desirable: -- For servers: addrs <- getAddrInfo (Just defaultHints { addrFamily = AF_INET6 , addrFlags = [AI_PASSIVE] }) Nothing (Just port) -- For clients: addrInfo <- getAddrInfo (Just defaultHints { addrFamily = AF_INET6 }) (Just "localhost") (Just port)
Use of IN6ADDR_SETV4MAPPED and dual stack sockets
This is a continuation of Connecting IPv4 client to IPv6 server: connection refused. I am experimenting with dual stack sockets and trying to understand what setsockopt with IPV6_V6ONLY is useful for. On the linked question I was advised that "Setting IPV6_V6ONLY to 0 can be useful if you also bind the server to an IPv6-mapped IPv4 address". I have done this below, and was expecting my server to be able to accept connections from both an IPv6 and an IPv4 client. But shockingly when I run my client with a V4 and a V6 socket, neither can connect! Can someone please tell me what I am doing wrong, or have I misunderstood IPv6 dual stack functionality all together? Server: void ConvertToV4MappedAddressIfNeeded(PSOCKADDR pAddr) { // if v4 address, convert to v4 mapped v6 address if (AF_INET == pAddr->sa_family) { IN_ADDR In4addr; SCOPE_ID scope = INETADDR_SCOPE_ID(pAddr); USHORT port = INETADDR_PORT(pAddr); In4addr = *(IN_ADDR*)INETADDR_ADDRESS(pAddr); ZeroMemory(pAddr, sizeof(SOCKADDR_STORAGE)); IN6ADDR_SETV4MAPPED( (PSOCKADDR_IN6)pAddr, &In4addr, scope, port ); } } addrinfo* result, hints; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; int nRet = getaddrinfo("powerhouse", "82", &hints, &result); SOCKET sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); int no = 0; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&no, sizeof(no)) != 0) return -1; ConvertToV4MappedAddressIfNeeded(result->ai_addr); if (bind(sock, result->ai_addr, 28/*result->ai_addrlen*/) == SOCKET_ERROR) return -1; if (listen(sock, SOMAXCONN) == SOCKET_ERROR) return -1; SOCKET sockClient = accept(sock, NULL, NULL); printf("Got one!\n"); Client: addrinfo* result, *pCurrent, hints; char szIPAddress[INET6_ADDRSTRLEN]; memset(&hints, 0, sizeof hints); // Must do this! hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; const char* pszPort = "82"; if (getaddrinfo("powerhouse", "82", &hints, &result) != 0) return -1; SOCKET sock = socket(AF_INET, result->ai_socktype, result->ai_protocol); int nRet = connect(sock, result->ai_addr, result->ai_addrlen);
My C skills are a bit rusty, so here is a counter-example written in Python. My local IPv4 address is 37.77.56.75, so that is what I will bind to. I kept it as simple as possible to focus on the concepts. This is the server side: #!/usr/bin/env python import socket # We bind to an IPv6 address, which contains an IPv6-mapped-IPv4-address, # port 5000 and we leave the flowinfo (an ID that identifies a flow, not used # a lot) and the scope-id (basically the interface, necessary if using # link-local addresses) host = '::ffff:37.77.56.75' port = 5000 flowinfo = 0 scopeid = 0 sockaddr = (host, port, flowinfo, scopeid) # Create an IPv6 socket, set IPV6_V6ONLY=0 and bind to the mapped address sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0) sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) sock.bind(sockaddr) # Listen and accept a connection sock.listen(0) conn = sock.accept() # Print the remote address print conn[1] Here we bind to an IPv6 address in the code, but the address is actually an IPv6-mapped IPv4 address, so in reality we are binding to an IPv4 address. This can be seen when looking at i.e. netstat: $ netstat -an | fgrep 5000 tcp4 0 0 37.77.56.75.5000 *.* LISTEN We can then use an IPv4 client to connect to this server: #!/usr/bin/env python import socket # Connect to an IPv4 address on port 5000 host = '37.77.56.75' port = 5000 sockaddr = (host, port) # Create an IPv4 socket and connect sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) conn = sock.connect(sockaddr) And the server will show us who connected, using IPv6 address representation: ('::ffff:37.77.56.76', 50887, 0, 0) In this example I connected from IPv4 host 37.77.56.76, and it choose port 50887 to connect from. In this example we are only listening on an IPv4 address (using IPv6 sockets, but it is still an IPv4 address) so IPv6-only clients will not be able to connect. A client with both IPv4 and IPv6 could of course use IPv6 sockets with IPv6-mapped-IPv4-addresses, but then it would not really be using IPv6, just an IPv6 representation of an IPv4 connection. A dual-stack server has to either: listen on the wildcard address, which will make the OS accept connections on any address (both IPv4 and IPv6) listen on both an IPv6 address and an IPv4 address (either by creating an IPv4 socket, or by creating an IPv6 socket and listening to an IPv6-mapped-IPv4-address as shown above) Using the wildcard address is the most simple. Just use the server example from above and replace the hostname: # We bind to the wildcard IPv6 address, which will make the OS listen on both # IPv4 and IPv6 host = '::' port = 5000 flowinfo = 0 scopeid = 0 sockaddr = (host, port, flowinfo, scopeid) My Mac OS X box shows this as: $ netstat -an | fgrep 5000 tcp46 0 0 *.5000 *.* LISTEN Notice the tcp46 which indicates that it listens on both address families. Unfortunately on Linux it only shows tcp6, even when listening on both families. Now for the most complicated example: listening on multiple sockets. #!/usr/bin/env python import select import socket # We bind to an IPv6 address, which contains an IPv6-mapped-IPv4-address sockaddr1 = ('::ffff:37.77.56.75', 5001, 0, 0) sock1 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0) sock1.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) sock1.bind(sockaddr1) sock1.listen(0) # And we bind to a real IPv6 address sockaddr2 = ('2a00:8640:1::224:36ff:feef:1d89', 5001, 0, 0) sock2 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0) sock2.bind(sockaddr2) sock2.listen(0) # Select sockets that become active sockets = [sock1, sock2] readable, writable, exceptional = select.select(sockets, [], sockets) for sock in readable: # Accept the connection conn = sock.accept() # Print the remote address print conn[1] When running this example both sockets are visible: $ netstat -an | fgrep 5000 tcp6 0 0 2a00:8640:1::224.5000 *.* LISTEN tcp4 0 0 37.77.56.75.5000 *.* LISTEN And now IPv6-only clients can connect to 2a00:8640:1::224:36ff:feef:1d89 and IPv4-only clients can connect to 37.77.56.75. Dual stack clients can choose which protocol they want to use.