Ok, I'll correct myself, the data sent through a dcc connection doesn't pass the server, setting up the dcc connection still uses the server.

As for the dcc chat itself: if server wants to send to client:
server uses /dcc chat client
server sends a DCC CHAT notice to client with an ip and port to connect to
client connects to given address
server and client can transfer data

For this to work, the server needs to have a public ip address and be reachable on that port, the client can be behind about anything that allows outgoing connections on that port.

This means you have to have a public ip address if you want to send the data. Apparently this doesn't work for you.

The other way is to have the client open the /dcc chat window, then the client needs to have a public ip. (You have less control about other people's connection...)

For this to work, you just put this in remotes:
on *:OPEN:=:{
msg =$nick your first line of text
play =$nick yourtextfile.txt 1
}

I don't know if it's possible to trigger or react to what's said in a dcc chat, so you'll probably send it to anywone who opens a dcc chat. You could try to see what channel a nick is in, or have him first send another private message with another trigger...

If both are behind a NAT/router/firewall, then you're stuck using the server I'm afraid.