<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def send(self, message, sid=None, tid=None, credit_request=None):
 """ Will send a message to the server that is passed in. The final unencrypted header is returned to the function that called this. :param message: An SMB message structure to send :param sid: A session_id that the message is sent for :param tid: A tree_id object that the message is sent for :param credit_request: Specifies extra credits to be requested with the SMB header :return: Request of the message that was sent """

        header = self._generate_packet_header(message, sid, tid,
                                              credit_request)

        # get the actual Session and TreeConnect object instead of the IDs
        session = self.session_table.get(sid, None) if sid else None

        tree = None
        if tid and session:
            if tid not in session.tree_connect_table.keys():
                error_msg = "Cannot find Tree with the ID %d in the session " \
                            "tree table" % tid
                raise smbprotocol.exceptions.SMBException(error_msg)
            tree = session.tree_connect_table[tid]

        if session and session.signing_required and session.signing_key:
            self._sign(header, session)
        request = Request(header)
        self.outstanding_requests[header['message_id'].get_value()] = request

        send_data = header.pack()
        if (session and session.encrypt_data) or (tree and tree.encrypt_data):
            send_data = self._encrypt(send_data, session)

        self.transport.send(send_data)

        return request