It take different approaches for TCP and for UDP.
Int TCP it's a bit of behind the scenes for developer - you just say send(buffer, buffer_size, tcp_connection_id) and that's it. But the OS tcp stack driver will first see for TCP maximum segment size (TCP MSS) for particular connection and first fragmentationsegmentation occurs there if your buffer length larger then MSS - it will break your data into tcp-segments of MSS size. MSS is calculated from MTU of your network adapter minus all required headers (ethernet, ip, tcp). It's done that way to avoid unneeded ip-fragmentationfragmentation at sending host. Then os driver forms ip packet and sends it out of network interface. Second and more fragmentations can occur on network path due to links there can have lesser MTU than your link.
For UDP it's bit harder, because it's you as developer has to form an UDP packet and it's application responsibility to fragment a data. You can form an UDP packet up to 65507 bytes of data and try to send it. And network driver can fragment it into lesser IP packets, according to MTU.